📄 win32.c
字号:
if (ebSDlen > 0) memcpy(d_entry->buf, ebSDptr, ebSDlen); d_entry->SDlen = ebSDlen; d_entry->fn = d_entry->buf + ebSDlen;#else d_entry->fn = d_entry->buf;#endif strcpy(d_entry->fn, G.filename); d_entry->perms = G.pInfo->file_attr; d_entry->gotTime = getNTfiletime(__G__ &(d_entry->Modft), &(d_entry->Accft), &(d_entry->Creft)); return PK_OK;} /* end function defer_dir_attribs() */int set_direc_attribs(__G__ d) __GDEF direntry *d;{ int errval; HANDLE hFile; /* File handle defined in NT */#ifdef __RSXNT__ char *ansi_name;#endif /* Win9x does not support setting directory time stamps. */ if (!IsWinNT()) return PK_OK; errval = PK_OK;#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ ansi_name = (char *)alloca(strlen(d->fn) + 1); INTERN_TO_ISO(d->fn, ansi_name);# define Ansi_Dirname ansi_name#else# define Ansi_Dirname d->fn#endif /* Open a handle to the directory before processing extra fields; we do this in case new security on file prevents us from updating time stamps. Although the WIN32 documentation recommends to use GENERIC_WRITE access flag to create the handle for SetFileTime(), this is too demanding for directories with the "read-only" attribute bit set. So we use the more specific flag FILE_WRITE_ATTRIBUTES here to request the minimum required access rights. (This problem is a Windows bug that has been silently fixed in Windows XP SP2.) */ hFile = CreateFile(Ansi_Dirname, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);#ifdef NTSD_EAS if (NtAtt(d)->SDlen > 0) { int err; if (QCOND2) { Info(slide, 1, ((char *)slide, " set attrib: %-22s ", FnFilter1(d->fn))); } /* set NTFS SD extra fields */ err = SetSD(__G__ Ansi_Dirname, NtAtt(d)->perms, NtAtt(d)->buf, NtAtt(d)->SDlen - EB_HEADSIZE); if (err == IZ_EF_TRUNC) { if (!QCOND2) Info(slide, 1, ((char *)slide, "%-22s ", FnFilter1(d->fn))); Info(slide, 1, ((char *)slide, LoadFarString(TruncNTSD), NtAtt(d)->SDlen-(EB_NTSD_L_LEN+EB_CMPRHEADLEN), "\n")); } else if (QCOND2) { Info(slide, 0, ((char *)slide, "\n")); } if (errval < err) errval = err; }#endif /* NTSD_EAS */ if (hFile == INVALID_HANDLE_VALUE) { Info(slide, 1, ((char *)slide, "warning: CreateFile() error %d (set file times for %s)\n", (int)GetLastError(), FnFilter1(d->fn))); if (!errval) errval = PK_WARN; } else { if (NtAtt(d)->gotTime) { FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME) ? &(NtAtt(d)->Modft) : NULL; FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME) ? &(NtAtt(d)->Accft) : NULL; FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME) ? &(NtAtt(d)->Creft) : NULL; if (!SetFileTime(hFile, pCreft, pAccft, pModft)) { Info(slide, 0, ((char *)slide, "warning: SetFileTime() for %s error %d\n", FnFilter1(d->fn), (int)GetLastError())); if (!errval) errval = PK_WARN; } } CloseHandle(hFile); } return errval;} /* end function set_direc_attribs() */#endif /* SET_DIR_ATTRIB */#ifdef TIMESTAMP/*************************//* Function stamp_file() *//*************************/int stamp_file(__GPRO__ ZCONST char *fname, time_t modtime){ FILETIME Modft; /* File time type defined in NT, `last modified' time */ HANDLE hFile; /* File handle defined in NT */ int errstat = 0; /* return status: 0 == "OK", -1 == "Failure" */ int fs_uses_loctime = FStampIsLocTime(__G__ fname);#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ char *ansi_name = (char *)alloca(strlen(fname) + 1); INTERN_TO_ISO(fname, ansi_name);# define Ansi_Fname ansi_name#else# define Ansi_Fname fname#endif /* open a handle to the file to prepare setting the mod-time stamp */ hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( hFile == INVALID_HANDLE_VALUE ) { errstat = -1; } else { /* convert time_t modtime into WIN32 native 64bit format */ UTIME_2_IZFILETIME(modtime, &Modft) /* set Access and Modification times of the file to modtime */ if (!SetFileTime(hFile, NULL, &Modft, &Modft)) { errstat = -1; } CloseHandle(hFile); } return errstat;#undef Ansi_Fname} /* end function stamp_file() */#endif /* TIMESTAMP *//***********************//* Function isfloppy() */ /* more precisely, is it removable? *//***********************/static int isfloppy(int nDrive) /* 1 == A:, 2 == B:, etc. */{ char rootPathName[4]; rootPathName[0] = (char)('A' + nDrive - 1); /* build the root path */ rootPathName[1] = ':'; /* name, e.g. "A:/" */ rootPathName[2] = '/'; rootPathName[3] = '\0'; return (GetDriveType(rootPathName) == DRIVE_REMOVABLE);} /* end function isfloppy() *//*****************************//* Function NTQueryVolInfo() *//*****************************//* * Note: 8.3 limits on filenames apply only to old-style FAT filesystems. * More recent versions of Windows (Windows NT 3.5 / Windows 4.0) * can support long filenames (LFN) on FAT filesystems. Check the * filesystem maximum component length field to detect LFN support. */static int NTQueryVolInfo(__GPRO__ const char *name){ /* static char lastRootPath[4] = ""; */ /* static int lastVolOldFAT; */ /* static int lastVolLocTim; */ char *tmp0; char tmp1[MAX_PATH], tmp2[MAX_PATH]; DWORD volSerNo, maxCompLen, fileSysFlags;#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ char *ansi_name = (char *)alloca(strlen(name) + 1); INTERN_TO_ISO(name, ansi_name); name = ansi_name;#endif if ((!strncmp(name, "//", 2) || !strncmp(name,"\\\\", 2)) && (name[2] != '\0' && name[2] != '/' && name[2] != '\\')) { /* GetFullPathname() and GetVolumeInformation() do not work * on UNC names. For now, we return "error". * **FIXME**: check if UNC name is mapped to a drive letter * and use mapped drive for volume info query. */ return FALSE; } if (isalpha((uch)name[0]) && (name[1] == ':')) tmp0 = (char *)name; else { if (!GetFullPathName(name, MAX_PATH, tmp1, &tmp0)) return FALSE; tmp0 = &tmp1[0]; } if (strncmp(G.lastRootPath, tmp0, 2) != 0) { /* For speed, we skip repeated queries for the same device */ strncpy(G.lastRootPath, tmp0, 2); /* Build the root path name, */ G.lastRootPath[2] = '/'; /* e.g. "A:/" */ G.lastRootPath[3] = '\0'; if (!GetVolumeInformation((LPCTSTR)G.lastRootPath, (LPTSTR)tmp1, (DWORD)MAX_PATH, &volSerNo, &maxCompLen, &fileSysFlags, (LPTSTR)tmp2, (DWORD)MAX_PATH)) { G.lastRootPath[0] = '\0'; return FALSE; } /* LFNs are available if the component length is > 12 */ G.lastVolOldFAT = (maxCompLen <= 12);/* G.lastVolOldFAT = !strncmp(strupr(tmp2), "FAT", 3); old version */ /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in * local time! */ G.lastVolLocTim = !strncmp(strupr(tmp2), "VFAT", 4) || !strncmp(tmp2, "HPFS", 4) || !strncmp(tmp2, "FAT", 3); } return TRUE;} /* end function NTQueryVolInfo() *//*****************************//* Function IsVolumeOldFAT() *//*****************************/static int IsVolumeOldFAT(__GPRO__ const char *name){ return (NTQueryVolInfo(__G__ name) ? G.lastVolOldFAT : FALSE);}#ifndef SFX/************************//* Function do_wild() */ /* identical to OS/2 version *//************************/char *do_wild(__G__ wildspec) __GDEF ZCONST char *wildspec; /* only used first time on a given dir */{/* these statics are now declared in SYSTEM_SPECIFIC_GLOBALS in w32cfg.h: static zDIR *wild_dir = NULL; static ZCONST char *wildname; static char *dirname, matchname[FILNAMSIZ]; static int notfirstcall=FALSE, have_dirname, dirnamelen;*/ char *fnamestart; struct zdirent *file; /* Even when we're just returning wildspec, we *always* do so in * matchname[]--calling routine is allowed to append four characters * to the returned string, and wildspec may be a pointer to argv[]. */ if (!G.notfirstcall) { /* first call: must initialize everything */ G.notfirstcall = TRUE; if (!iswild(wildspec)) { strncpy(G.matchname, wildspec, FILNAMSIZ); G.matchname[FILNAMSIZ-1] = '\0'; G.have_dirname = FALSE; G.wild_dir = NULL; return G.matchname; } /* break the wildspec into a directory part and a wildcard filename */ if ((G.wildname = MBSRCHR(wildspec, '/')) == (ZCONST char *)NULL && (G.wildname = MBSRCHR(wildspec, ':')) == (ZCONST char *)NULL) { G.dirname = "."; G.dirnamelen = 1; G.have_dirname = FALSE; G.wildname = wildspec; } else { ++G.wildname; /* point at character after '/' or ':' */ G.dirnamelen = G.wildname - wildspec; if ((G.dirname = (char *)malloc(G.dirnamelen+1)) == NULL) { Info(slide, 1, ((char *)slide, "warning: cannot allocate wildcard buffers\n")); strncpy(G.matchname, wildspec, FILNAMSIZ); G.matchname[FILNAMSIZ-1] = '\0'; return G.matchname; /* but maybe filespec was not a wildcard */ } strncpy(G.dirname, wildspec, G.dirnamelen); G.dirname[G.dirnamelen] = '\0'; /* terminate for strcpy below */ G.have_dirname = TRUE; } Trace((stderr, "do_wild: dirname = [%s]\n", FnFilter1(G.dirname))); if ((G.wild_dir = (zvoid *)Opendir(G.dirname)) != NULL) { if (G.have_dirname) { strcpy(G.matchname, G.dirname); fnamestart = G.matchname + G.dirnamelen; } else fnamestart = G.matchname; while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) { Trace((stderr, "do_wild: Readdir returns %s\n", FnFilter1(file->d_name))); strcpy(fnamestart, file->d_name); if (MBSRCHR(fnamestart, '.') == (char *)NULL) strcat(fnamestart, "."); if (match(fnamestart, G.wildname, TRUE WISEP) && /* skip "." and ".." directory entries */ strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) { Trace((stderr, "do_wild: match() succeeds\n")); /* remove trailing dot */ fnamestart = plastchar(fnamestart, strlen(fnamestart)); if (*fnamestart == '.') *fnamestart = '\0'; return G.matchname; } } /* if we get to here directory is exhausted, so close it */ Closedir((zDIR *)G.wild_dir); G.wild_dir = NULL; } Trace((stderr, "do_wild: Opendir(%s) returns NULL\n", FnFilter1(G.dirname))); /* return the raw wildspec in case that works (e.g., directory not * searchable, but filespec was not wild and file is readable) */ strncpy(G.matchname, wildspec, FILNAMSIZ); G.matchname[FILNAMSIZ-1] = '\0'; return G.matchname; } /* last time through, might have failed opendir but returned raw wildspec */ if (G.wild_dir == NULL) { G.notfirstcall = FALSE; /* reset for new wildspec */ if (G.have_dirname) free(G.dirname); return (char *)NULL; } /* If we've gotten this far, we've read and matched at least one entry * successfully (in a previous call), so dirname has been copied into * matchname already. */ if (G.have_dirname) { /* strcpy(G.matchname, G.dirname); */ fnamestart = G.matchname + G.dirnamelen; } else fnamestart = G.matchname; while ((file = Readdir((zDIR *)G.wild_dir)) != NULL) { Trace((stderr, "do_wild: readdir returns %s\n", FnFilter1(file->d_name))); strcpy(fnamestart, file->d_name); if (MBSRCHR(fnamestart, '.') == (char *)NULL) strcat(fnamestart, "."); if (match(fnamestart, G.wildname, TRUE WISEP)) { Trace((stderr, "do_wild: match() succeeds\n")); /* remove trailing dot */ fnamestart = plastchar(fnamestart, strlen(fnamestart)); if (*fnamestart == '.') *fnamestart = '\0'; return G.matchname;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -