scandir.c

来自「<Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.」· C语言 代码 · 共 1,259 行 · 第 1/3 页

C
1,259
字号
 *              getrelname gives:               ".\config.sys"
 *              getfullname gives:              "c:\config.sys"
 *
 * - if you called dir_buildlist(".\geraintd")
 *              getrelname gives:               ".\source\scandir.h"
 *              getfullname gives either
 *                      ".\geraintd\source\scandir.h"
 *                    or "c:\geraintd\source\scandir.h"
 *                   (depending on the implementation).
 *
 * To support this, we maintain the tree root name in the DIRLIST head, and
 * in each directory, the name of that directory relative to tree root.
 * Files just have the filename, so we need to prepend the directory name,
 * and (for getfullname) the tree root name as well
 *
 * We store the directory name with a trailing
 * slash to make concatenation easier
 *
 * -----
 */

/***************************************************************************
 * Function: dir_getrelname
 *
 * Purpose:
 *
 * Return the name of the current file relative to tree root
 */
LPSTR
dir_getrelname(DIRITEM cur)
{
        LPSTR name;
        int size;

        /* check this is a valid item */
        if (cur == NULL) {
                return(NULL);
        }
        /* remember to include the NULL when sizing */
        size = lstrlen(cur->direct->relname) + lstrlen(cur->name) + 1;
        name = gmem_get(hHeap, size);
        lstrcpy(name, cur->direct->relname);
        lstrcat(name, cur->name);

        return(name);
} /* dir_getrelname */

/***************************************************************************
 * Function: dir_getfullname
 *
 * Purpose:
 *
 * Return the fullname of the file (including the tree root passed in) 
 */
LPSTR
dir_getfullname(DIRITEM cur)
{
        LPSTR name;
        int size;
        LPSTR head;

        /* check this is a valid item */
        if (cur == NULL)  {
                return(NULL);
        }

        if (cur->direct->head->bFile) {
                return(cur->direct->head->rootname);
        }

        /* remember to include the NULL when sizing */
        size = lstrlen(cur->name) + 1;

        size += lstrlen(cur->direct->relname);

        /* add on root name */
        head = cur->direct->head->rootname;
        size += lstrlen(head);

        /* root names may not end in a slash. we need to
         * insert one in this case. Also, relnames always begin .\, so
         * we skip the . always, and the .\ if we don't need to
         * append a slash
         *
         */
        size--;         /* omit the '.' */
        if (*CharPrev(head, head+lstrlen(head)) == '\\') {
                size--;                         /* omit the .\ */
        }

        name = gmem_get(hHeap, size);

        lstrcpy(name, cur->direct->head->rootname);

        /* add relname and then name, omiting the .\ */

                /* skip . or .\ before relname */
                if (*CharPrev(head, head+lstrlen(head)) == '\\') {
                        lstrcat(name, &cur->direct->relname[2]);
                } else {
                        lstrcat(name, &cur->direct->relname[1]);
                }
                lstrcat(name, cur->name);
        return(name);
} /* dir_getfullname */


/***************************************************************************
 * Function: dir_getroot_list
 *
 * Purpose:
 *
 * Return the name of the tree root given a handle to the DIRLIST.
 */
LPSTR
dir_getroot_list(DIRLIST dl)
{
        if (dl == NULL) 
                return(NULL);
        return(dl->rootname);
} /* dir_getroot_list */

/***************************************************************************
 * Function: dir_getroot_item
 *
 * Purpose:
 *
 * Return the root name of this tree given a handle to a DIRITEM in the
 * list.
 */
LPSTR dir_getroot_item(DIRITEM item)
{
        if (item == NULL) 
                return(NULL);

        return(dir_getroot_list(item->direct->head));
}


/***************************************************************************
 * Function: dir_freerelname
 *
 * Purpose:
 *
 * Free up a relname that we allocated. This interface allows us
 * some flexibility in how we store relative and complete names
 *
 */
void
dir_freerelname(DIRITEM cur, LPSTR name)
{
        if((cur != NULL) && (name != NULL))
                        gmem_free(hHeap, name, lstrlen(name) +1);
} /* dir_freerelname */

/***************************************************************************
 * Function: dir_freefullname
 *
 * Purpose:
 *
 */
void
dir_freefullname(DIRITEM cur, LPSTR name)
{
        if (cur->direct->head->bFile)
                return;

        if (name != NULL) 
                gmem_free(hHeap, name, lstrlen(name) + 1);
} /* dir_freefullname            */

/***************************************************************************
 * Function: dir_freeroot_list
 *
 * Purpose:
 *
 * Free up rootname allocated by dir_getroot_list.
 * We just gave a pointer to the rootname, so do nothing.
 */
void
dir_freeroot_list(DIRLIST dl, LPSTR name)
{
        if ((dl == NULL) || (name == NULL)) {
                return;
        }
        return;
} /* dir_freeroot_list */

/***************************************************************************
 * Function: dir_freeroot_item
 *
 * Purpose:
 *
 * Free up memory alloc-ed by a call to dir_getroot_item. 
 */
void
dir_freeroot_item(DIRITEM item, LPSTR name)
{
        if ((item == NULL) || (name == NULL)) 
                return;
        dir_freeroot_list(item->direct->head, name);
}

/***************************************************************************
 * Function: dir_getopenname
 *
 * Purpose:
 *
 * Get an open-able name for the file. This will be the same as the fullname.
 */
LPSTR
dir_getopenname(DIRITEM item)
{
        LPSTR fname;

        if (item == NULL) 
                return(NULL);

        fname = dir_getfullname(item);

                return(fname);
} /* dir_getopenname */


/***************************************************************************
 * Function: dir_freeopenname
 *
 * Purpose:
 *
 * Free up memory created by a call to dir_getopenname(). This *may*
 * cause the file to be deleted if it was a temporary copy.
 */
void
dir_freeopenname(DIRITEM item, LPSTR openname)
{
        if ((item == NULL) || (openname == NULL)) 
                return;

        dir_freefullname(item, openname);
} /* dir_freeopenname */

/***************************************************************************
 * Function: dir_openfile
 *
 * Purpose:
 *
 * Return an open file handle to the file. 
 */
int
dir_openfile(DIRITEM item)
{
        LPSTR fname;
        int fh;
        OFSTRUCT os;

        fname = dir_getfullname(item);
        fh = OpenFile(fname, &os, OF_READ|OF_SHARE_DENY_NONE);
        dir_freefullname(item, fname);
        return(fh);
} /* dir_openfile */

/***************************************************************************
 * Function: dir_closefile
 *
 * Purpose:
 *
 * Close a file opened with dir_openfile.
 */
void
dir_closefile(DIRITEM item, int fh)
{
        _lclose(fh);

} /* dir_closefile */


/***************************************************************************
 * Function: dir_getfilesize
 *
 * Purpose:
 *
 * Return the file size (set during scanning) 
 */
long
dir_getfilesize(DIRITEM cur)
{
        /* check this is a valid item */
        if (cur == NULL)
                return(0);

        return(cur->size);
} /* dir_getfilesize */



/* ss_endcopy returns a number indicating the number of files copied,
   but we may have some local copies too.  We need to count these
   ourselves and add them in
*/

int nLocalCopies;        /* cleared in startcopy, ++d in copy
                                ** inspected in endcopy
                                */

/***************************************************************************
 * Function: dir_startcopy
 *
 * Purpose:
 *
 * Start a bulk copy 
 */
BOOL dir_startcopy(DIRLIST dl)
{
        nLocalCopies = 0;
        return(TRUE);

} /* dir_startcopy */
/***************************************************************************
 * Function: dir_endcopy
 *
 */
 
int dir_endcopy(DIRLIST dl)
{
        return(nLocalCopies);

} /* dir_endcopy */

/***************************************************************************
 * Function: dir_copy
 *
 * Purpose:
 *
 * Create a copy of the file, in the new root directory. Creates sub-dirs as
 * necessary. 
 *
 * Returns TRUE for success and FALSE for failure.
 */
BOOL dir_copy(DIRITEM item, LPSTR newroot)
{
        static char newpath[256];
        LPSTR relname, fullname;
        LPSTR pstart, pdest, pel;
        BOOL bOK;

        BY_HANDLE_FILE_INFORMATION bhfi;
        HANDLE hfile;

        /*
         * check that the newroot directory itself exists
         */
        if ((item == NULL) || !dir_isvaliddir(newroot)) {
                return(FALSE);
        }

        /*
         * name of file relative to the tree root
         */
        relname = dir_getrelname(item);

        /*
         * build the new pathname by concatenating the new root and
         * the old relative name. add one path element at a time and
         * ensure that the directory exists, creating it if necessary.
         */
        lstrcpy(newpath, newroot);

        /* add separating slash if not already there */
        if (*CharPrev(newpath, newpath+lstrlen(newpath)) != '\\') {
                lstrcat(newpath, "\\");
        }

        pstart = relname;
        while ( (pel = strchr(pstart, '\\')) != NULL) {

                /* found another element ending in slash. incr past the \\ */
                pel++;

                /*
                 * ignore .
                 */
                if (strncmp(pstart, ".\\", 2) != 0) {

                        pdest = &newpath[lstrlen(newpath)];
                        strncpy(pdest, pstart, pel - pstart);
                        pdest[pel - pstart] = '\0';

                        /* create subdir if necessary */
                        if (!dir_isvaliddir(newpath)) {
                                if (_mkdir(newpath) != 0) {
                                        return(FALSE);
                                }
                        }
                }

                pstart = pel;
        }

        /*
         * there are no more slashes, so pstart points at the final
         * element
         */
        lstrcat(newpath, pstart);

        fullname = dir_getfullname(item);

                bOK = CopyFile(fullname, newpath, FALSE);

                /* having copied the file, now copy the times, attributes */
                hfile = CreateFile(fullname, GENERIC_READ, 0, NULL,
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                bhfi.dwFileAttributes = GetFileAttributes(fullname);
                GetFileTime(hfile, &bhfi.ftCreationTime,
                                &bhfi.ftLastAccessTime, &bhfi.ftLastWriteTime);
                CloseHandle(hfile);

                hfile = CreateFile(newpath, GENERIC_WRITE, 0, NULL,
                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                SetFileTime(hfile, &bhfi.ftCreationTime,
                                   &bhfi.ftLastAccessTime,

⌨️ 快捷键说明

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