mirror of
https://github.com/digarok/gsplus.git
synced 2024-11-24 06:34:02 +00:00
map windows locked/hidden attributes.
This commit is contained in:
parent
a2d165840b
commit
c20257e5fe
@ -110,14 +110,20 @@ static int afp_to_filetype(struct AFP_Info *info, word16 *file_type, word32 *aux
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void afp_synchronize(struct AFP_Info *info) {
|
enum { prefer_prodos, prefer_hfs };
|
||||||
|
static void afp_synchronize(struct AFP_Info *info, int preference) {
|
||||||
// if ftype/auxtype is inconsistent between prodos and finder info, use
|
// if ftype/auxtype is inconsistent between prodos and finder info, use
|
||||||
// prodos as source of truth.
|
// prodos as source of truth.
|
||||||
word16 f;
|
word16 f;
|
||||||
word32 a;
|
word32 a;
|
||||||
if (finder_info_to_filetype(info->finder_info, &f, &a) != 0) return;
|
if (finder_info_to_filetype(info->finder_info, &f, &a) != 0) return;
|
||||||
if (f == info->prodos_file_type && a == info->prodos_aux_type) return;
|
if (f == info->prodos_file_type && a == info->prodos_aux_type) return;
|
||||||
file_type_to_finder_info(info->finder_info, info->prodos_file_type, info->prodos_aux_type);
|
if (preference == prefer_prodos)
|
||||||
|
file_type_to_finder_info(info->finder_info, info->prodos_file_type, info->prodos_aux_type);
|
||||||
|
else {
|
||||||
|
info->prodos_file_type = f;
|
||||||
|
info->prodos_aux_type = a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -508,6 +514,32 @@ static void get_file_xinfo(const char *path, struct file_info *fi) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static word16 map_attributes(DWORD dwFileAttributes) {
|
||||||
|
|
||||||
|
// 0x01 = read enable
|
||||||
|
// 0x02 = write enable
|
||||||
|
// 0x04 = invisible
|
||||||
|
// 0x08 = reserved
|
||||||
|
// 0x10 = reserved
|
||||||
|
// 0x20 = backup needed
|
||||||
|
// 0x40 = rename enable
|
||||||
|
// 0x80 = destroy enable
|
||||||
|
|
||||||
|
word16 access = 0;
|
||||||
|
|
||||||
|
if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||||
|
access = readEnable;
|
||||||
|
else
|
||||||
|
access = readEnable | writeEnable | renameEnable | destroyEnable;
|
||||||
|
|
||||||
|
if (dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
|
||||||
|
access |= fileInvisible;
|
||||||
|
|
||||||
|
// map FILE_ATTRIBUTE_ARCHIVE to backup needed bit?
|
||||||
|
|
||||||
|
return access;
|
||||||
|
}
|
||||||
|
|
||||||
static word32 get_file_info(const char *path, struct file_info *fi) {
|
static word32 get_file_info(const char *path, struct file_info *fi) {
|
||||||
|
|
||||||
|
|
||||||
@ -575,7 +607,7 @@ static word32 get_file_info(const char *path, struct file_info *fi) {
|
|||||||
|
|
||||||
// map FILE_ATTRIBUTE_ARCHIVE to backup needed bit?
|
// map FILE_ATTRIBUTE_ARCHIVE to backup needed bit?
|
||||||
|
|
||||||
fi->access = access;
|
fi->access = map_attributes(info.dwFileAttributes);
|
||||||
|
|
||||||
|
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
@ -588,36 +620,66 @@ static word32 set_file_info(const char *path, struct file_info *fi) {
|
|||||||
if (fi->has_fi && fi->storage_type != 0x0d && fi->storage_type != 0x0f) {
|
if (fi->has_fi && fi->storage_type != 0x0d && fi->storage_type != 0x0f) {
|
||||||
char *rpath = append_string(path, ":AFP_AfpInfo");
|
char *rpath = append_string(path, ":AFP_AfpInfo");
|
||||||
|
|
||||||
HANDLE h = CreateFile(rpath, GENERIC_READ | GENERIC_WRITE,
|
HANDLE h = CreateFile(rpath, GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
FILE_SHARE_READ , NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (h == INVALID_HANDLE_VALUE) return map_last_error();
|
if (h == INVALID_HANDLE_VALUE) return map_last_error();
|
||||||
|
|
||||||
WriteFile(h, &fi->afp, sizeof(struct AFP_Info), NULL, NULL);
|
WriteFile(h, &fi->afp, sizeof(struct AFP_Info), NULL, NULL);
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo -- also map hidden / read only attributes.
|
|
||||||
|
|
||||||
if (fi->create_date.dwLowDateTime || fi->create_date.dwHighDateTime
|
if (fi->create_date.dwLowDateTime || fi->create_date.dwHighDateTime
|
||||||
|| fi->modified_date.dwLowDateTime || fi->modified_date.dwHighDateTime) {
|
|| fi->modified_date.dwLowDateTime || fi->modified_date.dwHighDateTime) {
|
||||||
// SetFileInformationByHandle can modify dates.
|
// SetFileInformationByHandle can modify dates.
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
h = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
h = CreateFile(path, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (h == INVALID_HANDLE_VALUE) return map_last_error();
|
if (h == INVALID_HANDLE_VALUE) return map_last_error();
|
||||||
|
|
||||||
// just use FILETIME in the file_info if WIN32?
|
|
||||||
|
|
||||||
FILE_BASIC_INFO fbi;
|
FILE_BASIC_INFO fbi;
|
||||||
|
FILE_BASIC_INFO newfbi;
|
||||||
memset(&fbi, 0, sizeof(fbi));
|
memset(&fbi, 0, sizeof(fbi));
|
||||||
|
memset(&newfbi, 0, sizeof(newfbi));
|
||||||
|
|
||||||
fbi.CreationTime.LowPart = fi->create_date.dwLowDateTime;
|
BOOL ok;
|
||||||
fbi.CreationTime.HighPart = fi->create_date.dwHighDateTime;
|
ok = GetFileInformationByHandleEx(h, FileBasicInfo, &fbi, sizeof(fbi));
|
||||||
//fbi.ChangeTime.LowPart = fi->modified_date.dwLowDateTime; //?
|
|
||||||
//fbi.ChangeTime.HighPart = fi->modified_date.dwHighDateTime; //?
|
|
||||||
fbi.LastWriteTime.LowPart = fi->modified_date.dwLowDateTime;
|
|
||||||
fbi.LastWriteTime.HighPart = fi->modified_date.dwHighDateTime;
|
|
||||||
|
|
||||||
BOOL ok = SetFileInformationByHandle(h, FileBasicInfo, &fbi, sizeof(fbi));
|
int delta = 0;
|
||||||
|
|
||||||
|
word16 old_access = map_attributes(fbi.FileAttributes);
|
||||||
|
if (fi->access && fi->access != old_access) {
|
||||||
|
newfbi.FileAttributes = fbi.FileAttributes;
|
||||||
|
|
||||||
|
if (fi->access & fileInvisible) {
|
||||||
|
delta = 1;
|
||||||
|
newfbi.FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
|
||||||
|
}
|
||||||
|
// hfs fst only marks it read enable if all are clear.
|
||||||
|
word16 locked = writeEnable | destroyEnable | renameEnable;
|
||||||
|
if ((fi->access & locked) == 0) {
|
||||||
|
delta = 1;
|
||||||
|
newfbi.FileAttributes |= FILE_ATTRIBUTE_READONLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo -- compare against nt file time to see if it's actually changed.
|
||||||
|
// to prevent time stamp truncation.
|
||||||
|
|
||||||
|
if (fi->create_date.dwLowDateTime || fi->create_date.dwHighDateTime) {
|
||||||
|
delta = 1;
|
||||||
|
newfbi.CreationTime.LowPart = fi->create_date.dwLowDateTime;
|
||||||
|
newfbi.CreationTime.HighPart = fi->create_date.dwHighDateTime;
|
||||||
|
}
|
||||||
|
if (fi->modified_date.dwLowDateTime || fi->modified_date.dwHighDateTime) {
|
||||||
|
delta = 1;
|
||||||
|
newfbi.LastWriteTime.LowPart = fi->modified_date.dwLowDateTime;
|
||||||
|
newfbi.LastWriteTime.HighPart = fi->modified_date.dwHighDateTime;
|
||||||
|
//newfbi.ChangeTime.LowPart = fi->modified_date.dwLowDateTime; //?
|
||||||
|
//newfbi.ChangeTime.HighPart = fi->modified_date.dwHighDateTime; //?
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delta)
|
||||||
|
ok = SetFileInformationByHandle(h, FileBasicInfo, &newfbi, sizeof(newfbi));
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1197,7 +1259,7 @@ static word32 fst_set_file_info(int class, const char *path) {
|
|||||||
|
|
||||||
// one more check... if ftype/auxtype doesn't match the ftype/auxtype in finder info
|
// one more check... if ftype/auxtype doesn't match the ftype/auxtype in finder info
|
||||||
// update finder info
|
// update finder info
|
||||||
if (fi.has_fi) afp_synchronize(&fi.afp);
|
if (fi.has_fi) afp_synchronize(&fi.afp, prefer_prodos);
|
||||||
|
|
||||||
return set_file_info(path, &fi);
|
return set_file_info(path, &fi);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user