这里贴上32位的deltree代码
/* deltree32.h */
#ifndef __DELTREE32_H
#define __DELTREE32_H
//#define __DEBUG
// 错误定义
#define ERR_OK 0x0000
#define ERR_UNEXPECT_POINTER 0x0001
#define ERR_NODE_REMOVE_FAILED 0x0002
#define ERR_INVAILD_POINTER 0x0003
#define ERR_DS_EMPTY 0x0004
#define ERR_FS_TREE_EMPTY 0x0005
#define ERR_DS_PUSH_FAILED 0x0006
#define ERR_DS_POP_FAILED 0x0007
#define ERR_UNKNOWN 0xffff
typedef enum { tpFile, tpDir } ATTRIB_T;
typedef struct tagFSNodeInfo {
WORD wDirCnt; // 文件夹数
WORD wFileCnt; // 文件数
} ATTR_FS_NODE_INFO;
typedef struct tagFSTreeNode {
ATTRIB_T oFSNodeType; // 节点类型(目录还是文件)
ATTR_FS_NODE_INFO oInfo; // 节点信息
char *pFName; // 文件名(oFSNodeType = tpDir时表示目录名)
struct tagFSTreeNode *pParent; // 父节点
struct tagFSTreeNode *pPrev; // 该层的前一个节点
struct tagFSTreeNode *pNext; // 该层的下一个节点
struct tagFSTreeNode *pDesecentHead; // 下一层节点链表表头
struct tagFSTreeNode *pDesecentTail; // 下一层节点链表表尾
} ATTR_FS_TREE_NODE;
typedef struct tagDymStackNode {
ATTR_FS_TREE_NODE *pFSTreeNode; // 动态栈的每个单元所容纳的是ATTR_FS_TREE_NODE类型的变量
struct tagDymStackNode *pNext;
struct tagDymStackNode *pPrev;
} ATTR_DYM_STACK_NODE;
// 错误报告函数
void ErrReport( WORD wErrId ) {
switch( wErrId ) {
case 0x0001:
printf("Unexpected pointer!\n");
break;
case 0x0002:
printf("Specified logical tree node cannot be removed due to it is not empty!\n");
break;
case 0x0003:
printf("Invailed pointer reference!\n");
break;
case 0x0004:
printf("Specified dynamic stack is empty!\n");
break;
case 0x0005:
printf("Specified logical tree is empty!\n");
break;
case 0x0006:
printf("Push stack failed!\n");
break;
case 0x0007:
printf("Pop stack failed!\n");
break;
case 0xffff:
printf("Unexpected error!\n");
break;
}
}
// 创建一个节点
ATTR_FS_TREE_NODE *CreateFSTreeNode( ATTRIB_T oFSNodeType, const char *pFName ) {
ATTR_FS_TREE_NODE *pNode = new ATTR_FS_TREE_NODE;
assert( pNode );
pNode->oFSNodeType = oFSNodeType;
pNode->pFName = new char[strlen(pFName) + 1];
assert( pNode->pFName );
strcpy( pNode->pFName, pFName );
pNode->oInfo.wDirCnt = (WORD)0;
pNode->oInfo.wFileCnt = (WORD)0;
pNode->pParent = (ATTR_FS_TREE_NODE *)0;
pNode->pNext = (ATTR_FS_TREE_NODE *)0;
pNode->pPrev = (ATTR_FS_TREE_NODE *)0;
pNode->pDesecentHead = (ATTR_FS_TREE_NODE *)0;
pNode->pDesecentTail = (ATTR_FS_TREE_NODE *)0;
return pNode;
}
// 指定节点中添加一个字节点
WORD AddFSTreeNode( ATTR_FS_TREE_NODE *pNode, ATTR_FS_TREE_NODE *pSubNode ) {
if( pNode == (ATTR_FS_TREE_NODE *)0 || pSubNode == (ATTR_FS_TREE_NODE *)0 )
return (WORD)ERR_UNEXPECT_POINTER;
// 该节点没有子节点
if( pNode->pDesecentHead == (ATTR_FS_TREE_NODE *)0 ) {
pNode->pDesecentHead = pSubNode;
pNode->pDesecentTail = pSubNode;
pSubNode->pParent = pNode;
// 更新节点信息
if( pSubNode->oFSNodeType == tpFile )
pNode->oInfo.wFileCnt++;
else
pNode->oInfo.wDirCnt++;
}
else {
pNode->pDesecentTail->pNext = pSubNode;
pSubNode->pPrev = pNode->pDesecentTail;
pSubNode->pParent = pNode;
pNode->pDesecentTail = pSubNode;
if( pSubNode->oFSNodeType == tpFile )
pNode->oInfo.wFileCnt++;
else
pNode->oInfo.wDirCnt++;
}
return (WORD)ERR_OK;
}
// 删除指定节点
WORD DelFSTreeNode( ATTR_FS_TREE_NODE **dpNode ) {
ATTR_FS_TREE_NODE *pNode;
ATTR_FS_TREE_NODE *pParent;
if( dpNode == (ATTR_FS_TREE_NODE **)0 )
return (WORD)ERR_INVAILD_POINTER;
if( (pNode = (*dpNode)) == (ATTR_FS_TREE_NODE *)0 )
return (WORD)ERR_UNEXPECT_POINTER;
// 获取欲删除节点的父节点
pParent = pNode->pParent;
// 若删除的节点是目录节点,但目录不为空,则删除失败
if( pNode->oFSNodeType == tpDir && ( pNode->oInfo.wDirCnt + pNode->oInfo.wFileCnt ) != (WORD)0 )
return (WORD)ERR_NODE_REMOVE_FAILED;
if( pNode->pPrev != (ATTR_FS_TREE_NODE *)0 )
pNode->pPrev->pNext = pNode->pNext;
if( pNode->pNext != (ATTR_FS_TREE_NODE *)0 )
pNode->pNext->pPrev = pNode->pPrev;
if( pParent != (ATTR_FS_TREE_NODE *)0 ) {
// 若欲删除的节点是该层的首节点
if( pNode == pParent->pDesecentHead ) {
pParent->pDesecentHead = pNode->pNext;
if( pParent->pDesecentHead != (ATTR_FS_TREE_NODE *)0 )
pParent->pDesecentHead->pPrev = (ATTR_FS_TREE_NODE *)0;
}
// 反之欲删除的节点是该层的尾节点
else if( pNode == pParent->pDesecentTail ) {
pParent->pDesecentTail = pNode->pPrev;
if( pParent->pDesecentTail != (ATTR_FS_TREE_NODE *)0 )
pParent->pDesecentTail->pNext = (ATTR_FS_TREE_NODE *)0;
}
// 更新父节点信息
if( pNode->oFSNodeType == tpFile )
pParent->oInfo.wFileCnt--;
else
pParent->oInfo.wDirCnt--;
}
// 删除节点
delete []pNode->pFName;
delete pNode;
*dpNode = (ATTR_FS_TREE_NODE *)0;
return (WORD)ERR_OK;
}
// 将节点压入动态栈
WORD DSPush( ATTR_DYM_STACK_NODE **dpStackTop, ATTR_FS_TREE_NODE *pNode ) {
ATTR_DYM_STACK_NODE *pStackTop;
if( dpStackTop == (ATTR_DYM_STACK_NODE **)0 )
return (WORD)ERR_INVAILD_POINTER;
pStackTop = *dpStackTop;
// 栈为空
if( pStackTop == (ATTR_DYM_STACK_NODE *)0 ) {
pStackTop = *dpStackTop = new ATTR_DYM_STACK_NODE;
pStackTop->pFSTreeNode = pNode;
pStackTop->pNext = (ATTR_DYM_STACK_NODE *)0;
pStackTop->pPrev = (ATTR_DYM_STACK_NODE *)0;
}
// 栈非空则进行尾部压栈操作
else {
pStackTop->pNext = new ATTR_DYM_STACK_NODE;
pStackTop->pNext->pPrev = pStackTop;
pStackTop = pStackTop->pNext;
pStackTop->pNext = (ATTR_DYM_STACK_NODE *)0;
pStackTop->pFSTreeNode = pNode;
*dpStackTop = pStackTop;
}
return (WORD)ERR_OK;
}
// 将节点从动态栈中弹出
WORD DSPop( ATTR_DYM_STACK_NODE **dpStackTop, ATTR_FS_TREE_NODE **pNode ) {
ATTR_DYM_STACK_NODE *pStackTop;
if( dpStackTop == (ATTR_DYM_STACK_NODE **)0 || pNode == (ATTR_FS_TREE_NODE **)0 )
return (WORD)ERR_INVAILD_POINTER;
pStackTop = *dpStackTop;
// 栈为空
if( pStackTop == (ATTR_DYM_STACK_NODE *)0 )
return (WORD)ERR_DS_EMPTY;
(*pNode) = pStackTop->pFSTreeNode;
(*dpStackTop) = pStackTop->pPrev;
if( (*dpStackTop) != (ATTR_DYM_STACK_NODE *)0 )
(*dpStackTop)->pNext = (ATTR_DYM_STACK_NODE *)0;
delete pStackTop;
return (WORD)ERR_OK;
}
// 删除逻辑树(仅当发生错误时使用)
WORD DestoryFSTree( ATTR_FS_TREE_NODE **dpRoot ) {
ATTR_FS_TREE_NODE *pNode;
ATTR_FS_TREE_NODE *pNodeTmp;
ATTR_FS_TREE_NODE **dpNode;
ATTR_DYM_STACK_NODE **dpStackTop;
if( dpRoot == (ATTR_FS_TREE_NODE **)0 )
return (WORD)ERR_INVAILD_POINTER;
if( *dpRoot == (ATTR_FS_TREE_NODE *)0 )
return (WORD)ERR_FS_TREE_EMPTY;
// 初始化栈
dpStackTop = new (ATTR_DYM_STACK_NODE *);
assert(dpStackTop);
*dpStackTop = (ATTR_DYM_STACK_NODE *)0;
// 初始化临时节点
dpNode = new (ATTR_FS_TREE_NODE *);
assert(dpNode);
*dpNode = (ATTR_FS_TREE_NODE *)0;
if( DSPush( dpStackTop, *dpRoot ) != (WORD)ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_PUSH_FAILED;
}
while( (*dpStackTop) != (ATTR_DYM_STACK_NODE *)0 ) {
if( DSPop( dpStackTop, dpNode ) != (WORD)ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_POP_FAILED;
}
pNode = (*dpNode)->pDesecentHead;
while( pNode != (ATTR_FS_TREE_NODE *)0 ) {
// 若是目录则压栈
if( pNode->oFSNodeType == tpDir ) {
if( DSPush( dpStackTop, pNode ) != ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_PUSH_FAILED;
}
pNode = pNode->pNext;
}
// 若是文件则直接删除该节点
else {
pNodeTmp = pNode->pNext;
delete []pNode->pFName;
delete pNode;
pNode = pNodeTmp;
}
}
// 该层所有节点处理完之后删除当前节点
delete []((*dpNode)->pFName);
delete (*dpNode);
}
// 删除完成后处理临时变量
delete dpStackTop;
delete dpNode;
*dpRoot = (ATTR_FS_TREE_NODE *)0;
return (WORD)ERR_OK;
}
// 将物理路径(就是硬文件系统)映射到内存路径树(对应该软件的数据结构)
ATTR_FS_TREE_NODE *DrawPhy2LogTree( const char *path ) {
LPWIN32_FIND_DATAA pFd;
ATTR_FS_TREE_NODE *p;
ATTR_FS_TREE_NODE *pRoot;
ATTR_FS_TREE_NODE **dpNode;
ATTR_DYM_STACK_NODE **dpStackTop; // 动态栈
ATTR_DYM_STACK_NODE *pStackTop; // 错误处理时使用
HANDLE hFind; // 搜索使用句柄
char *pTempStr; // 临时字符串
char *pImm; // 这个也是
int len;
bool isDone; // 搜索任务是否完成(默认没有完成)
if( path == (const char *)0 )
return (ATTR_FS_TREE_NODE *)0;
// 初始化动态栈
dpStackTop = new (ATTR_DYM_STACK_NODE *);
assert(dpStackTop);
(*dpStackTop) = (ATTR_DYM_STACK_NODE *)0;
// 初始化临时节点
dpNode = new (ATTR_FS_TREE_NODE *);
assert(dpNode);
(*dpNode) = (ATTR_FS_TREE_NODE *)0;
// 初始化pFd
pFd = new WIN32_FIND_DATAA;
assert(pFd);
// 创建根节点
pRoot = CreateFSTreeNode( tpDir, path );
// 根压栈
if( DSPush( dpStackTop, pRoot ) != (WORD)ERR_OK ) {
ErrReport( (WORD)ERR_DS_PUSH_FAILED );
DestoryFSTree( &pRoot );
delete pFd;
delete dpStackTop;
delete dpNode;
return (ATTR_FS_TREE_NODE *)0;
}
// 栈不为空时进行循环搜索
while( (*dpStackTop) != (ATTR_DYM_STACK_NODE *)0 ) {
if( DSPop( dpStackTop, dpNode ) != (WORD)ERR_OK ) {
ErrReport( (WORD)ERR_DS_POP_FAILED );
DestoryFSTree( &pRoot );
delete pFd;
delete dpStackTop;
delete dpNode;
return (ATTR_FS_TREE_NODE *)0;
}
isDone = false;
// 创建查找串
len = (int)strlen( (*dpNode)->pFName );
pTempStr = new char[len + 5];
strcpy(pTempStr, (*dpNode)->pFName);
strcat(pTempStr,"\\*.*");
// 搜索文件及文件夹
hFind = FindFirstFileA( pTempStr, pFd );
while( isDone != true ) {
// '.'或'..'不是我们所要的目录或文件
if( pFd->cFileName[0] != '.' ) {
pImm = new char[len + strlen( (const char *)pFd->cFileName ) + 2];
strcpy(pImm, (*dpNode)->pFName);
strcat(pImm, "\\");
strcat(pImm, (const char *)pFd->cFileName);
// 当前查找到的对象是文件夹
if( pFd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
// 添加到当前节点中作为子节点
p = CreateFSTreeNode( tpDir, pImm );
delete []pImm;
AddFSTreeNode( *dpNode, p );
// 将目录压栈
if( DSPush( dpStackTop, p ) != (WORD)ERR_OK ) {
ErrReport( (WORD)ERR_DS_PUSH_FAILED );
DestoryFSTree( &pRoot );
delete pFd;
delete dpStackTop;
delete dpNode;
return (ATTR_FS_TREE_NODE *)0;
}
}
// 当前查找到的对象是文件
else {
p = CreateFSTreeNode( tpFile, pImm );
delete []pImm;
AddFSTreeNode( *dpNode, p );
}
}
// 查找下一个对象
if( !FindNextFileA( hFind, pFd ) ) {
// 查找结束
if( GetLastError() == ERROR_NO_MORE_FILES )
isDone = true;
else {
// 发生不可预料的错误
// 这里进行错误处理
ErrReport( (WORD)ERR_UNKNOWN );
// 清空栈
while( *dpStackTop != (ATTR_DYM_STACK_NODE *)0 ) {
pStackTop = (*dpStackTop)->pPrev;
delete (*dpStackTop);
*dpStackTop = pStackTop;
}
// 删除树(对此函数不进行错误处理)
DestoryFSTree( &pRoot );
delete pFd;
delete dpStackTop;
delete dpNode;
return (ATTR_FS_TREE_NODE *)0;
}
}
}
// 完成搜索后关闭句柄以便下次使用
FindClose(hFind);
// 删除搜索字串
delete []pTempStr;
}
// 收尾工作
delete pFd;
delete dpStackTop;
delete dpNode;
return pRoot;
}
// 删除指定目录树
WORD DelTree32( ATTR_FS_TREE_NODE **dpRoot ) {
ATTR_FS_TREE_NODE *pNode;
ATTR_FS_TREE_NODE *pNodeTmp;
ATTR_FS_TREE_NODE **dpNode;
ATTR_DYM_STACK_NODE **dpStackTop;
bool flag; // 判断是否有子目录
if( dpRoot == (ATTR_FS_TREE_NODE **)0 )
return (WORD)ERR_INVAILD_POINTER;
if( (*dpRoot) == (ATTR_FS_TREE_NODE *)0 )
return (WORD)ERR_FS_TREE_EMPTY;
dpStackTop = new (ATTR_DYM_STACK_NODE *);
assert(dpStackTop);
*dpStackTop = (ATTR_DYM_STACK_NODE *)0;
dpNode = new (ATTR_FS_TREE_NODE *);
assert(dpNode);
*dpNode = (ATTR_FS_TREE_NODE *)0;
if( DSPush( dpStackTop, *dpRoot ) != (WORD)ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_PUSH_FAILED;
}
while( (*dpStackTop) != (ATTR_DYM_STACK_NODE *)0 ) {
if( DSPop( dpStackTop, dpNode ) != (WORD)ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_POP_FAILED;
}
flag = false;
pNode = (*dpNode)->pDesecentHead;
while( pNode != (ATTR_FS_TREE_NODE *)0 ) {
// 是目录则压栈
if( pNode->oFSNodeType == tpDir ) {
if( flag != true ) {
// 若有子目则要将当前层压入栈,以便以后处理
if( DSPush( dpStackTop, *dpNode ) != (WORD)ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_PUSH_FAILED;
}
flag = true;
}
// 将子目录压栈
if( DSPush( dpStackTop, pNode ) != (WORD)ERR_OK ) {
delete dpStackTop;
delete dpNode;
return (WORD)ERR_DS_PUSH_FAILED;
}
pNode = pNode->pNext;
}
// 是文件则删除之
else {
#ifndef __DEBUG
DeleteFileA( pNode->pFName );
#endif
printf("Deleted file - %s\n", pNode->pFName);
// 删除逻辑节点
pNodeTmp = pNode->pNext;
DelFSTreeNode( &pNode );
pNode = pNodeTmp;
}
}
// 若没有该目录下没有文件和子目录,则删除之
if( flag == false ) {
#ifndef __DEBUG
RemoveDirectoryA( (*dpNode)->pFName );
#endif
printf("Delete directory - %s\n", (*dpNode)->pFName);
// 删除逻辑节点
DelFSTreeNode( dpNode );
}
}
delete dpStackTop;
delete dpNode;
return (WORD)ERR_OK;
}
#endif
/* main.cpp */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include "deltree32.h"
int main(int argc, char *argv[]) {
WORD wRes;
ATTR_FS_TREE_NODE *pRoot;
WIN32_FIND_DATAA oFd;
HANDLE hFind;
char *pPath;
char c;
int len, i;
if( argc < 2 ) {
printf("Deltree32 simple version\n");
printf("Usage: %s <directory>\n", argv[0]);
printf("eg. %s d:\\testdir - to delete a directory in specified logical driver\n", argv[0]);
printf("eg. %s testdir - to delete a directory in current driver\n", argv[0]);
return (int)1;
}
else {
// 首先合并路径
for( len = (int)strlen(argv[1]), i = 2; i < argc; len += (int)strlen(argv[i++]) );
pPath = new char[len + argc + 1];
for(strcpy(pPath, argv[1]), i = 2; i < argc; ++i ) {
strcat(pPath,"\x20\0");
strcat(pPath,argv[i]);
}
// 修正
if( pPath[len - 1] == '\\' )
pPath[len - 1] = '\0';
// 判断是否为根目录
if( strlen(pPath) == 2 && pPath[1] == ':' ) {
printf("Remove the root of a logical driver is forbidden!\n");
delete []pPath;
return (int)1;
}
// 验证输入目录是否存在
hFind = FindFirstFileA( "D:\\winhex", &oFd );
if( hFind == INVALID_HANDLE_VALUE ) {
delete []pPath;
printf("Path not found!\n");
return (int)1;
}
FindClose( hFind );
do {
printf("Do you really want to remove directory %s within all files? (Y/N) ", pPath);
c = getchar();
} while( c != 'Y' && c != 'y' && c != 'N' && c != 'n' );
if( c == 'N' || c == 'n' )
return (int)1;
// 收集目录树
pRoot = DrawPhy2LogTree( pPath );
if( pRoot == (ATTR_FS_TREE_NODE *)0 )
return (int)1;
if( (wRes = DelTree32( &pRoot )) != (WORD)ERR_OK ) {
// 报告错误
ErrReport( wRes );
delete []pPath;
return (int)1;
}
delete []pPath;
printf("All done!\n");
}
return (int)0;
}