⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nt.c

📁 压缩算法的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*---------------------------------------------------------------------------

  nt.c                                              Last updated:  15 Aug 94

  WinNT-specific routines for use with Info-ZIP's UnZip 5.1 and later.
  (Borrowed, pilfered and plundered code from OS/2 and MS-DOS versions and
  from ZIP; modified as necessary.)

  Contains:  GetLoadPath()
             opendir()
             readdir()
             closedir()
             mapattr()
             getNTfiletime()
             close_outfile()
             isfloppy()
             IsVolumeOldFAT()
             IsFileNameValid()
             map2fat()
             checkdir()
             do_wild()
             mapname()
             version()

  ---------------------------------------------------------------------------*/

#include <windows.h>
#include "unzip.h"


#define MKDIR(path,mode)   mkdir(path)

struct direct
{
    char    reserved [21];
    char    ff_attrib;
    short   ff_ftime;
    short   ff_fdate;
    long    size;
    char    d_name[MAX_PATH];
    int     d_first;
    HANDLE  d_hFindFile;
};


static int created_dir;         /* used by mapname(), checkdir() */
static int renamed_fullpath;    /* ditto */
static int fnlen;               /* ditto */
static unsigned nLabelDrive;    /* ditto */



#ifdef SFX

/**************************/
/* Function GetLoadPath() */
/**************************/

char *GetLoadPath(void) 
{
#ifdef MSC
    extern char *_pgmptr;
    return _pgmptr;

#else    /* use generic API call */
    GetModuleFileName(NULL, filename, FILNAMSIZ);
    return filename;
#endif

} /* end function GetLoadPath() */





#else /* !SFX */

/**********************/        /* Borrowed from ZIP 2.0 sources             */
/* Function opendir() */        /* Difference: no special handling for       */
/**********************/        /*             hidden or system files.       */

static struct direct *opendir(n)
    const char *n;  /* directory to open */
{
    struct direct *d;       /* malloc'd return value */
    char *p;                /* malloc'd temporary string */
    WIN32_FIND_DATA fd;
    int len = strlen(n);

    /* Start searching for files in the MSDOS directory n */

    if ((d = (struct direct *)malloc(sizeof(struct direct))) == NULL ||
        (p = malloc(strlen(n) + 5)) == NULL)
    {
        if (d != (struct direct *)NULL)
            free((void *)d);
        return (struct direct *)NULL;
    }
    strcpy(p, n);
    if (p[len-1] == ':')
        p[len++] = '.';   /* x: => x:. */
    else if (p[len-1] == '/' || p[len-1] == '\\')
        --len;            /* foo/ => foo */
    strcpy(p+len, "/*");

    if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd))) {
        free((voidp *)d);
        free((voidp *)p);
        return NULL;
    }
    strcpy(d->d_name, fd.cFileName);

    free((voidp *)p);
    d->d_first = 1;
    return d;

} /* end of function opendir() */




/**********************/        /* Borrowed from ZIP 2.0 sources             */
/* Function readdir() */        /* Difference: no special handling for       */
/**********************/        /*             hidden or system files.       */

static struct direct *readdir(d)
    struct direct *d;         /* directory stream from which to read */
{
    /* Return pointer to first or next directory entry, or NULL if end. */

    if ( d->d_first )
        d->d_first = 0;
    else
    {
        WIN32_FIND_DATA fd;

        if ( !FindNextFile(d->d_hFindFile, &fd) )
            return NULL;

        strcpy(d->d_name, fd.cFileName);
    }
    return (struct direct *)d;

} /* end of function readdir() */




/***********************/
/* Function closedir() */       /* Borrowed from ZIP 2.0 sources */
/***********************/

static void closedir(d)
    struct direct *d;         /* directory stream to close */
{
    FindClose(d->d_hFindFile);
    free(d);
}

#endif /* ?SFX */




/**********************/
/* Function mapattr() */
/**********************/

/* Identical to MS-DOS, OS/2 versions.                                       */
/* However, NT has a lot of extra permission stuff, so this function should  */
/*  probably be extended in the future.                                      */

int mapattr()
{
    /* set archive bit (file is not backed up): */
    pInfo->file_attr = (unsigned)(crec.external_file_attributes | 32) & 0xff;
    return 0;

} /* end function mapattr() */




/****************************/      /* Get the file time in a format that */
/* Function getNTfiletime() */      /* can be used by SetFileTime() in NT */
/****************************/

int getNTfiletime(FILETIME *ft)
{
    FILETIME lft;      /* 64-bit value made up of two 32 bit [low & high] */
    WORD wDOSDate;     /* for converting from DOS date to Windows NT      */
    WORD wDOSTime;

    /* Copy and/or convert time and date variables, if necessary;   */
    /* then set the file time/date.                                 */
    wDOSTime = (WORD)lrec.last_mod_file_time;
    wDOSDate = (WORD)lrec.last_mod_file_date;

    /* The DosDateTimeToFileTime() function converts a DOS date/time    */
    /* into a 64 bit Windows NT file time                               */
    if (!DosDateTimeToFileTime(wDOSDate, wDOSTime, &lft))
    {
        PRINTF("DosDateTime failed: %d\n", GetLastError());
        return FALSE;
    }
    if (!LocalFileTimeToFileTime( &lft, ft))
    {
        PRINTF("LocalFileTime failed: %d\n", GetLastError());
        *ft = lft;
    }
    return TRUE;
}




/****************************/
/* Function close_outfile() */
/****************************/

void close_outfile()
{
    FILETIME ft;       /* File time type defined in NT */
    HANDLE hFile;      /* File handle defined in NT    */
    int gotTime;

    /* don't set the time stamp on standard output */
    if (cflag) {
        fclose(outfile);
        return;
    }

    gotTime = getNTfiletime(&ft);

    /* Close the file and then re-open it using the Win32
     * CreateFile call, so that the file can be created
     * with GENERIC_WRITE access, otherwise the SetFileTime
     * call will fail. */
    fclose(outfile);

    hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
         FILE_ATTRIBUTE_NORMAL, NULL);
    if ( hFile == INVALID_HANDLE_VALUE ) {
        FPRINTF(stderr, "\nCreateFile error %d when trying set file time\n",
                GetLastError());
    }
    else {
        if (gotTime)
            if (!SetFileTime(hFile, NULL, NULL, &ft))
                PRINTF("\nSetFileTime failed: %d\n", GetLastError());
        CloseHandle(hFile);
    }

    /* HG: I think this could be done in the CreateFile call above - just  */
    /*     replace 'FILE_ATTRIBUTE_NORMAL' with 'pInfo->file_attr & 0x7F'  */
    if (!SetFileAttributes(filename, pInfo->file_attr & 0x7F))
        FPRINTF(stderr, "\nwarning (%d): could not set file attributes\n",
                GetLastError());

    return;

} /* end function close_outfile() */



/* ============================================================================
*/



/***********************/
/* Function isfloppy() */   /* more precisely, is it removable? */
/***********************/

static int isfloppy(int nDrive)   /* 1 == A:, 2 == B:, etc. */
{
    char rootPathName[4];

    rootPathName[0] = 'A' + nDrive - 1;   /* Build the root path name, */
    rootPathName[1] = ':';                /* e.g. "A:/"                */
    rootPathName[2] = '/';
    rootPathName[3] = '\0';

    return (GetDriveType(rootPathName) == DRIVE_REMOVABLE);

} /* end function isfloppy() */




/*****************************/
/* Function IsVolumeOldFAT() */
/*****************************/

/*
 * 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.
 *        [GRR:  this routine is only used to determine whether spaces in
 *        filenames are supported...]
 */

static int IsVolumeOldFAT(char *name)
{
    char     *tmp0;
    char      rootPathName[4];
    char      tmp1[MAX_PATH], tmp2[MAX_PATH];
    unsigned  volSerNo, maxCompLen, fileSysFlags;

    if (isalpha(name[0]) && (name[1] == ':'))
        tmp0 = name;
    else
    {
        GetFullPathName(name, MAX_PATH, tmp1, &tmp0);
        tmp0 = &tmp1[0];
    }
    strncpy(rootPathName, tmp0, 3);   /* Build the root path name, */
    rootPathName[3] = '\0';           /* e.g. "A:/"                */

    GetVolumeInformation(rootPathName, tmp1, MAX_PATH, &volSerNo,
                         &maxCompLen, &fileSysFlags, tmp2, MAX_PATH);

    /* Long Filenames (LFNs) are available if the component length is > 12 */
    return maxCompLen <= 12;
/*  return !strncmp(strupr(tmp2), "FAT", 3);   old version */

}




/******************************/
/* Function IsFileNameValid() */
/******************************/

static int IsFileNameValid(char *name)
{
    HFILE    hf;
    OFSTRUCT of;

    hf = OpenFile(name, &of, OF_READ | OF_SHARE_DENY_NONE);
    if (hf == HFILE_ERROR)
        switch (GetLastError())
        {
            case ERROR_INVALID_NAME:
            case ERROR_FILENAME_EXCED_RANGE:
                return FALSE;
            default:
                return TRUE;
        }
    else
        _lclose(hf);
    return TRUE;
}




/**********************/
/* Function map2fat() */        /* Identical to OS/2 version */
/**********************/

void map2fat(pathcomp, pEndFAT)
    char *pathcomp, **pEndFAT;
{
    char *ppc = pathcomp;       /* variable pointer to pathcomp */
    char *pEnd = *pEndFAT;      /* variable pointer to buildpathFAT */
    char *pBegin = *pEndFAT;    /* constant pointer to start of this comp. */
    char *last_dot = NULL;      /* last dot not converted to underscore */
    int dotname = FALSE;        /* flag:  path component begins with dot */
                                /*  ("." and ".." don't count) */
    register unsigned workch;   /* hold the character being tested */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -