文件夹拷贝,判断,生成当前用户权限的文件夹

使用到的API:
CreateDirectory:创建目录
FindFirstFile,FindNextFile 查找文件
RemoveDirectory:删除空目录
GetFileAttributes:获取文件属性
CreateSymbolicLink:创建符号链接
GetDriveType:获取盘符
SHFileOperation:拷贝文件

拷贝文件夹有两种方案,一种是通过SHFileOperation来拷贝,代码简洁,只需要填写SHFILEOPSTRUCT的参数就可以。另一种是用FindFirstFile,FindNextFile 查找文件递归去复制。

方法一

BOOL CopyFolder(LPTSTR pFrom, LPTSTR pTo)
{
    SHFILEOPSTRUCT FileOp={0};
    ZeroMemory(&FileOp, sizeof(SHFILEOPSTRUCT));
    FileOp.fFlags = FOF_NOCONFIRMATION| //不出现确认对话框
    FOF_NOCONFIRMMKDIR ; //需要时直接创建一个文件夹,不需用户确定
    //FileOp.fFlags = FOF_NO_UI;
    FileOp.pFrom = pFrom;
    FileOp.pTo = pTo;
    FileOp.wFunc = FO_COPY;
    if( SHFileOperation(&FileOp) == 0){
        cout<<" copy file success!!!"<<endl;
        return TRUE;
    }else{
        cout<<"copy file failed!!!  "<<endl;
        return FALSE;
    }
}

注意:当我尝试隐藏所有弹框(确认框,进度条,冲突选项等)FileOp.fFlags = FOF_NO_UI时。在拷贝较大的文件夹时会报错,返回值是32(进程无法访问文件,因为另一个程序正在使用此文件),用上面的参数就会弹出进度条,就不会报错。

方法二:
通过FindFirstFile,FindNextFile 递归查找文件,用copyfile复制文件,不会存在方法一的问题,还能拷贝隐藏文件,CreateDirectory创建头目录时,可以设置属性为只有当前用户可以访问。

BOOL CopyDir(LPTSTR pszSrcPath,LPTSTR pszDstPath)
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    TCHAR tmpsrc[256];
    _tcscpy(tmpsrc,pszSrcPath);
    _tcscat(tmpsrc,L"\\*.*");
    hFind = FindFirstFile(tmpsrc, &FindFileData);
    if(hFind == INVALID_HANDLE_VALUE)
        return FALSE;
    CreateDirectory(pszDstPath,NULL);

    do
    {
        TCHAR newdst[256];
        _tcscpy(newdst,pszDstPath);
        if(newdst[_tcslen(newdst)]!='\\')
        _tcscat(newdst,L"\\");
        _tcscat(newdst,FindFileData.cFileName);

        TCHAR newsrc[256];
        _tcscpy(newsrc,pszSrcPath);
        if(newsrc[_tcslen(newsrc)]!='\\')
        _tcscat(newsrc,L"\\");

        _tcscat(newsrc,FindFileData.cFileName);
        if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY){
            if(_tcscmp(FindFileData.cFileName,L".")!=0&&_tcscmp(FindFileData.cFileName,L"..")!=0)
            CopyDir(newsrc,newdst);
        }else
            CopyFile(newsrc,newdst,TRUE);

    }while(FindNextFile(hFind,&FindFileData));
        FindClose(hFind);
    return TRUE;
}

判断是否文件夹,通过GetFileAttributes获取文件属性,文件夹是FILE_ATTRIBUTE_DIRECTORY属性,可能会是隐藏文件夹FILE_ATTRIBUTE_HIDDEN

BOOL IsDirectory(LPTSTR lpDirPath)
{
    DWORD dwRes = GetFileAttributes(lpDirPath);
    if(dwRes == INVALID_FILE_ATTRIBUTES){
        cout<<"GetFileAttributes failed"<<endl;
        return FALSE;
    }

    if( dwRes == (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY )
        || dwRes == FILE_ATTRIBUTE_DIRECTORY )
        return TRUE;
    return FALSE;
}

创建只有当前用户有访问权限的文件夹
原理:获取当前用户名,通过LookupAccountName用户的psid,再通过AddAccessAllowedAce获取pacl,用SetSecurityDescriptorDacl设置SECURITY_DESCRIPTOR,最后配置SECURITY_ATTRIBUTES


BOOL IsDirExist(LPTSTR pszDir)
{
    DWORD dwAttrib = GetFileAttributes(pszDir);
    return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}

BOOL CreateDir(LPTSTR pszDirName)
{
    if(IsDirExist(pszDirName))
        return FALSE;

    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;

    BYTE aclBuffer[1024];
    PACL pacl = (PACL)&aclBuffer;

    BYTE sidBuffer[100];
    PSID psid = (PSID)&sidBuffer;
    DWORD sidBufferSize = 100;
    TCHAR domainBuffer[80];
    DWORD domainBufferSize = 80;
    SID_NAME_USE snu;

    DWORD dwBufferSize = 100;
    TCHAR UserName[100];

    GetUserName(UserName,&dwBufferSize);

    InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);

    InitializeAcl(pacl,1024,ACL_REVISION);
    LookupAccountName(0,UserName,psid,&sidBufferSize,domainBuffer,&domainBufferSize,&snu);
    AddAccessAllowedAce(pacl,ACL_REVISION,GENERIC_ALL,psid);
    SetSecurityDescriptorDacl(&sd,TRUE,pacl,FALSE);

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = FALSE;
    sa.lpSecurityDescriptor = &sd;

    CreateDirectory(pszDirName,&sa);
    return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值