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 + -
显示快捷键?