int my_getvolumeinfo (const TCHAR *root) { DWORD v, err; int ret = 0; TCHAR volume[MAX_DPATH]; v = GetFileAttributesSafe (root); err = GetLastError (); if (v == INVALID_FILE_ATTRIBUTES) return -1; if (!(v & FILE_ATTRIBUTE_DIRECTORY)) return -2; /* if (v & FILE_ATTRIBUTE_READONLY) ret |= MYVOLUMEINFO_READONLY; */ if (GetVolumePathName (root, volume, sizeof (volume))) { TCHAR fsname[MAX_DPATH]; DWORD comlen; DWORD flags; if (GetVolumeInformation (volume, NULL, 0, NULL, &comlen, &flags, fsname, sizeof fsname / sizeof (TCHAR))) { //write_log (_T("Volume %s FS=%s maxlen=%d flags=%08X\n"), volume, fsname, comlen, flags); if (flags & FILE_NAMED_STREAMS) ret |= MYVOLUMEINFO_STREAMS; } } return ret; }
int fsdb_set_file_attrs (a_inode *aino) { uae_u32 tmpmask; uae_u8 fsdb[UAEFSDB2_LEN]; uae_u32 mode; tmpmask = filesys_parse_mask (aino->amigaos_mode); mode = GetFileAttributesSafe (aino->nname); if (mode == INVALID_FILE_ATTRIBUTES) return ERROR_OBJECT_NOT_AROUND; mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; mode = 0; if ((tmpmask & (A_FIBF_WRITE | A_FIBF_DELETE)) == 0) mode |= FILE_ATTRIBUTE_READONLY; if (!(tmpmask & A_FIBF_ARCHIVE)) mode |= FILE_ATTRIBUTE_ARCHIVE; if (tmpmask & A_FIBF_PURE) mode |= FILE_ATTRIBUTE_SYSTEM; if (tmpmask & A_FIBF_HIDDEN) mode |= FILE_ATTRIBUTE_HIDDEN; SetFileAttributesSafe (aino->nname, mode); aino->dirty = 1; if (aino->volflags & MYVOLUMEINFO_STREAMS) { if (needs_fsdb (aino)) { create_uaefsdb (aino, fsdb, mode); write_uaefsdb (aino->nname, fsdb); } else { delete_uaefsdb (aino->nname); } } return 0; }
struct my_openfile_s *my_open (const TCHAR *name, int flags) { struct my_openfile_s *mos; HANDLE h; DWORD DesiredAccess = GENERIC_READ; DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; DWORD CreationDisposition = OPEN_EXISTING; DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; DWORD attr; const TCHAR *namep; TCHAR path[MAX_DPATH]; if (currprefs.win32_filesystem_mangle_reserved_names == false) { _tcscpy (path, PATHPREFIX); _tcscat (path, name); namep = path; } else { namep = name; } mos = xmalloc (struct my_openfile_s, 1); if (!mos) return NULL; attr = GetFileAttributesSafe (name); if (flags & O_TRUNC) CreationDisposition = CREATE_ALWAYS; else if (flags & O_CREAT) CreationDisposition = OPEN_ALWAYS; if (flags & O_WRONLY) DesiredAccess = GENERIC_WRITE; if (flags & O_RDONLY) { DesiredAccess = GENERIC_READ; CreationDisposition = OPEN_EXISTING; } if (flags & O_RDWR) DesiredAccess = GENERIC_READ | GENERIC_WRITE; if (CreationDisposition == CREATE_ALWAYS && attr != INVALID_FILE_ATTRIBUTES && (attr & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) SetFileAttributesSafe (name, FILE_ATTRIBUTE_NORMAL); h = CreateFile (namep, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL); if (h == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_ACCESS_DENIED && (DesiredAccess & GENERIC_WRITE)) { DesiredAccess &= ~GENERIC_WRITE; h = CreateFile (namep, DesiredAccess, ShareMode, NULL, CreationDisposition, FlagsAndAttributes, NULL); if (h == INVALID_HANDLE_VALUE) err = GetLastError(); } if (h == INVALID_HANDLE_VALUE) { write_log (_T("failed to open '%s' %x %x err=%d\n"), namep, DesiredAccess, CreationDisposition, err); xfree (mos); mos = NULL; goto err; } } mos->h = h; err: //write_log (_T("open '%s' = %x\n"), namep, mos ? mos->h : 0); return mos; }
int my_existsdir (const TCHAR *name) { DWORD attr; attr = GetFileAttributesSafe (name); if (attr == INVALID_FILE_ATTRIBUTES) return 0; if (attr & FILE_ATTRIBUTE_DIRECTORY) return 1; return 0; }
/* For an a_inode we have newly created based on a filename we found on the * native fs, fill in information about this file/directory. */ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino) { int mode, winmode, oldamode; uae_u8 fsdb[UAEFSDB2_LEN]; int reset = 0; if((mode = GetFileAttributesSafe (aino->nname)) == INVALID_FILE_ATTRIBUTES) { write_log (_T("GetFileAttributes('%s') failed! error=%d, aino=%p dir=%d\n"), aino->nname, GetLastError(), aino, aino->dir); return 0; } aino->dir = (mode & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; if ((base->volflags & MYVOLUMEINFO_STREAMS) && read_uaefsdb (aino->nname, NULL, fsdb)) { aino->amigaos_mode = do_get_mem_long ((uae_u32 *)(fsdb + 1)); xfree (aino->comment); aino->comment = NULL; if (fsdb[5 + 2 * 257]) aino->comment = my_strdup_ansi ((char*)fsdb + 5 + 2 * 257); xfree (aino_from_buf (base, fsdb, &winmode)); if (winmode == mode) /* no Windows-side editing? */ return 1; write_log (_T("FS: '%s' protection flags edited from Windows-side\n"), aino->nname); reset = 1; /* edited from Windows-side -> use Windows side flags instead */ } oldamode = aino->amigaos_mode; aino->amigaos_mode = A_FIBF_EXECUTE | A_FIBF_READ; if (!(FILE_ATTRIBUTE_ARCHIVE & mode)) aino->amigaos_mode |= A_FIBF_ARCHIVE; if (!(FILE_ATTRIBUTE_READONLY & mode)) aino->amigaos_mode |= A_FIBF_WRITE | A_FIBF_DELETE; if (FILE_ATTRIBUTE_SYSTEM & mode) aino->amigaos_mode |= A_FIBF_PURE; if (FILE_ATTRIBUTE_HIDDEN & mode) aino->amigaos_mode |= A_FIBF_HIDDEN; aino->amigaos_mode = filesys_parse_mask(aino->amigaos_mode); aino->amigaos_mode |= oldamode & A_FIBF_SCRIPT; if (reset && (base->volflags & MYVOLUMEINFO_STREAMS)) { create_uaefsdb (aino, fsdb, mode); write_uaefsdb (aino->nname, fsdb); } return 1; }
static a_inode *aino_from_buf (a_inode *base, uae_u8 *buf, int *winmode) { uae_u32 mode; a_inode *aino = xcalloc (a_inode, 1); uae_u8 *buf2; TCHAR *s; buf2 = buf + 604; mode = do_get_mem_long ((uae_u32 *)(buf + 1)); buf += 5; if (buf2[0]) { aino->aname = my_strdup ((TCHAR*)buf2); } else { aino->aname = au_fs ((char*)buf); } buf += 257; buf2 += 257 * 2; if (buf2[0]) { aino->nname = build_nname (base->nname, (TCHAR*)buf2); } else { s = au_fs ((char*)buf); aino->nname = build_nname (base->nname, s); xfree (s); } buf += 257; aino->comment = *buf != '\0' ? my_strdup_ansi ((char*)buf) : 0; buf += 81; aino->amigaos_mode = mode; *winmode = do_get_mem_long ((uae_u32 *)buf); aino->dir = ((*winmode) & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; *winmode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; aino->has_dbentry = 0; aino->dirty = 0; aino->db_offset = 0; if((mode = GetFileAttributesSafe (aino->nname)) == INVALID_FILE_ATTRIBUTES) { write_log (_T("xGetFileAttributes('%s') failed! error=%d, aino=%p\n"), aino->nname, GetLastError (), aino); return aino; } aino->dir = (mode & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; return aino; }
static int recycle (const TCHAR *name) { DWORD dirattr = GetFileAttributesSafe (name); bool isdir = dirattr != INVALID_FILE_ATTRIBUTES && (dirattr & FILE_ATTRIBUTE_DIRECTORY); const TCHAR *namep; TCHAR path[MAX_DPATH]; if (currprefs.win32_filesystem_mangle_reserved_names == false) { _tcscpy (path, PATHPREFIX); _tcscat (path, name); namep = path; } else { namep = name; } if (currprefs.win32_norecyclebin || isdir || currprefs.win32_filesystem_mangle_reserved_names == false) { if (isdir) return RemoveDirectory (namep) ? 0 : -1; else return DeleteFile (namep) ? 0 : -1; } else { SHFILEOPSTRUCT fos; HANDLE h; h = CreateFile (namep, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h != INVALID_HANDLE_VALUE) { LARGE_INTEGER size; if (GetFileSizeEx (h, &size)) { if (size.QuadPart == 0) { CloseHandle (h); return DeleteFile (namep) ? 0 : -1; } } CloseHandle (h); } /* name must be terminated by \0\0 */ TCHAR *p = xcalloc (TCHAR, _tcslen (namep) + 2); int v; _tcscpy (p, namep); memset (&fos, 0, sizeof (fos)); fos.wFunc = FO_DELETE; fos.pFrom = p; fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NORECURSION | FOF_SILENT; v = SHFileOperation (&fos); xfree (p); switch (v) { case 0xb7: //DE_ERROR_MAX case 0x7c: //DE_INVALIDFILES case 0x402: // "unknown error" v = ERROR_FILE_NOT_FOUND; break; case 0x75: //DE_OPCANCELLED: case 0x10000: //ERRORONDEST: case 0x78: //DE_ACCESSDENIEDSRC: case 0x74: //DE_ROOTDIR: v = ERROR_ACCESS_DENIED; break; } SetLastError (v); return v ? -1 : 0; } }
int fsdb_exists (const TCHAR *nname) { return GetFileAttributesSafe (nname) != INVALID_FILE_ATTRIBUTES; }
static int write_uaefsdb (const TCHAR *dir, uae_u8 *fsdb) { TCHAR *p; HANDLE h; DWORD written = 0, dirflag, dirattr; DWORD attr = INVALID_FILE_ATTRIBUTES; FILETIME t1, t2, t3; int time_valid = FALSE; int ret = 0; const TCHAR *namep; TCHAR path[MAX_DPATH]; if (currprefs.win32_filesystem_mangle_reserved_names == false) { _tcscpy (path, PATHPREFIX); _tcscat (path, dir); namep = path; } else { namep = dir; } p = make_uaefsdbpath (dir, NULL); dirattr = GetFileAttributesSafe (dir); dirflag = FILE_ATTRIBUTE_NORMAL; if (dirattr != INVALID_FILE_ATTRIBUTES && (dirattr & FILE_ATTRIBUTE_DIRECTORY)) dirflag = FILE_FLAG_BACKUP_SEMANTICS; /* argh... */ h = CreateFile (namep, GENERIC_READ, 0, NULL, OPEN_EXISTING, dirflag, NULL); if (h != INVALID_HANDLE_VALUE) { if (GetFileTime (h, &t1, &t2, &t3)) time_valid = TRUE; CloseHandle (h); } h = CreateFile (p, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (fsdb_debug) { TCHAR *an, *nn, *co; an = au_fs ((char*)fsdb + 5); nn = au_fs ((char*)fsdb + 262); co = au_fs ((char*)fsdb + 519); write_log (_T("write_uaefsdb '%s' = %x\n"), p, h); write_log (_T("v=%02x flags=%08x an='%s' nn='%s' c='%s'\n"), fsdb[0], ((uae_u32*)(fsdb+1))[0], an, nn, co); xfree (co); xfree (nn); xfree (an); } if (h == INVALID_HANDLE_VALUE && GetLastError () == ERROR_ACCESS_DENIED) { attr = GetFileAttributes (p); if (attr != INVALID_FILE_ATTRIBUTES) { if (attr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) { SetFileAttributes (p, attr & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)); h = CreateFile (p, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (fsdb_debug) write_log (_T("write_uaefsdb (2) '%s' = %x\n"), p, h); } } } if (h != INVALID_HANDLE_VALUE) { WriteFile (h, fsdb, UAEFSDB2_LEN, &written, NULL); CloseHandle (h); if (written == UAEFSDB2_LEN) { if (fsdb_debug) write_log (_T("->ok\n")); ret = 1; goto end; } } if (fsdb_debug) write_log (_T("->fail %d, %d\n"), written, GetLastError ()); DeleteFile (p); end: if (attr != INVALID_FILE_ATTRIBUTES) SetFileAttributes (p, attr); if (time_valid) { h = CreateFile (namep, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, dirflag, NULL); if (h != INVALID_HANDLE_VALUE) { SetFileTime (h, &t1, &t2, &t3); CloseHandle (h); } } xfree (p); return ret; }