陈皓专栏 【空谷幽兰,心如皓月】

芝兰生于深谷,不以无人而不芳;君子修道立德,不为困穷而改节。

用户操作
[即时聊天] [发私信] [加为好友]
陈皓ID:haoel
485265次访问,排名97好友51人,关注者74
芝兰生于空谷,不以无人而不芳;君子修道立德,不为困穷而改节。
haoel的文章
原创 71 篇
翻译 0 篇
转载 0 篇
评论 1052 篇
陈皓的公告
Email & MSN
haoel@hotmail.com
最近评论
liuxi:LS 两个command都是命令的意思 例如 cc -o test.o -c -g test.c这样的命令.
targets : prerequisites ; command
command
这个的意思是命令你可以选择写在先决条件(prerequisites)的后面用分号隔开;也可以另起一行用tab开始些命令。
figoshen:楼上的,楼主的程序我跑了没有问题,你说的的多加(int*)是问题我觉得加不加都一样了
silvervi:大哥,文章有错误

在VS 2005里面加了断点专门跑了一下,对照局部变量里面虚函数表的实际地址,错误跟我之前想的一样,少了一次解引用

正确的应该如下

cout << "虚函数表地址:" << (int *)*(int *)(&b) << endl;

cout &……
miansha:走过留名

谢谢LZ,学习并谨记
new_my_program:我还是个学生,但就我们学生的角度来看,像清华大学出版社你们这些人是没资格出书的。一个老师如果教育学生犯罪那就是个垃圾老师,你们出书的本来更是影响几代人,比一般的老师的影响力更大的多,你们的垃圾程度是可想而知的。以前看了《清华梦的破灭》这个文章后,我对心目中的清华园产生了严重的鄙视,现在再看了陈皓大哥的帖子,我更是鄙视你们。进清华的学生是何等的厉害,何等的意气风发。但是出清华的学生呢,好的就留……
文章分类
收藏
    相册
    我的BLOG
    耗子小筑(非技术)(RSS)
    陈皓专栏(技 术)(RSS)
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 以程序的方式操纵NTFS的文件权限(下)收藏

    新一篇: 以程序的方式操纵NTFS的文件权限(上) | 旧一篇: C/C++内存问题检查利器—Purify (五)

        // 
        // STEP 14: 把一个 access-allowed ACE 加入到新的DACL
        //     前面的循环拷贝了所有的非继承且SID为其它用户的ACE,退出循环的第一件事
        // 就是加入我们指定的ACE。请注意首先先动态装载了一个AddAccessAllowedAceEx
        // API函数,如果装载不成功,就调用AddAccessAllowedAce函数。前一个函数仅
        // Windows 2000以后的版本支持,NT则没有,我们为了使用新版本的函数,我们首
        // 先先检查一下当前系统中可不可以装载这个函数,如果可以则就使用。使用动态链接
        // 使用静态链接的好处是,程序运行时不会因为没有这个API函数而报错。
        // 
        // Ex版的函数多出了一个参数AceFlag(第三人参数),用这个参数我们可以来设置一
        // 个叫ACE_HEADER的结构,以便让我们所设置的ACE可以被其子目录所继承下去,而 
        // AddAccessAllowedAce函数不能定制这个参数,在AddAccessAllowedAce函数
        // 中,其会把ACE_HEADER这个结构设置成非继承的。
        // 
          _AddAccessAllowedAceEx = (AddAccessAllowedAceExFnPtr)
                GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
                "AddAccessAllowedAceEx");

          if (_AddAccessAllowedAceEx) {
               if (!_AddAccessAllowedAceEx(pNewACL, ACL_REVISION2,
                  CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE ,
                    dwAccessMask, pUserSID)) {
                 _tprintf(TEXT("AddAccessAllowedAceEx() failed. Error %d\n"),
                       GetLastError());
                 __leave;
              }
          }else{
              if (!AddAccessAllowedAce(pNewACL, ACL_REVISION2, 
                    dwAccessMask, pUserSID)) {
                 _tprintf(TEXT("AddAccessAllowedAce() failed. Error %d\n"),
                       GetLastError());
                 __leave;
              }
          }

          // 
          // STEP 15: 按照已存在的ACE的顺序拷贝从父目录继承而来的ACE
          // 
          if (fDaclPresent && AclInfo.AceCount) {

             for (; 
                  CurrentAceIndex < AclInfo.AceCount;
                  CurrentAceIndex++) {

                // 
                // STEP 16: 从文件(目录)的DACL中继续取ACE
                // 
                if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {
                   _tprintf(TEXT("GetAce() failed. Error %d\n"), 
                         GetLastError());
                   __leave;
                }

                // 
                // STEP 17: ACE加入到新的DACL
                // 
                if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
                      ((PACE_HEADER) pTempAce)->AceSize)) {
                   _tprintf(TEXT("AddAce() failed. Error %d\n"), 
                         GetLastError());
                   __leave;
                }
             }
          }

          // 
          // STEP 18: 把新的ACL设置到新的SD
          // 
          if (!SetSecurityDescriptorDacl(&newSD, TRUE, pNewACL, 
                FALSE)) {
             _tprintf(TEXT("SetSecurityDescriptorDacl() failed. Error %d\n"),
                   GetLastError());
             __leave;
          }

          // 
          // STEP 19: 把老的SD中的控制标记再拷贝到新的SD,我们使用的是一个叫 
          // SetSecurityDescriptorControl() API函数,这个函数同样只存在于
          // Windows 2000以后的版本中,所以我们还是要动态地把其从advapi32.dll 
          // 中载入,如果系统不支持这个函数,那就不拷贝老的SD的控制标记了。
          // 
          _SetSecurityDescriptorControl =(SetSecurityDescriptorControlFnPtr)
                GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
                "SetSecurityDescriptorControl");
          if (_SetSecurityDescriptorControl) {

             SECURITY_DESCRIPTOR_CONTROL controlBitsOfInterest = 0;
             SECURITY_DESCRIPTOR_CONTROL controlBitsToSet = 0;
             SECURITY_DESCRIPTOR_CONTROL oldControlBits = 0;
             DWORD dwRevision = 0;

             if (!GetSecurityDescriptorControl(pFileSD, &oldControlBits,
                &dwRevision)) {
                _tprintf(TEXT("GetSecurityDescriptorControl() failed.")
                      TEXT("Error %d\n"), GetLastError());
                __leave;
             }

             if (oldControlBits & SE_DACL_AUTO_INHERITED) {
                controlBitsOfInterest =
                   SE_DACL_AUTO_INHERIT_REQ |
                   SE_DACL_AUTO_INHERITED ;
                controlBitsToSet = controlBitsOfInterest;
             }
             else if (oldControlBits & SE_DACL_PROTECTED) {
                controlBitsOfInterest = SE_DACL_PROTECTED;
                controlBitsToSet = controlBitsOfInterest;
             }       

             if (controlBitsOfInterest) {
                if (!_SetSecurityDescriptorControl(&newSD,
                   controlBitsOfInterest,
                   controlBitsToSet)) {
                   _tprintf(TEXT("SetSecurityDescriptorControl() failed.")
                         TEXT("Error %d\n"), GetLastError());
                   __leave;
                }
             }
          }

          // 
          // STEP 20: 把新的SD设置设置到文件的安全属性中(千山万水啊,终于到了)
          // 
          if (!SetFileSecurity(lpszFileName, secInfo,
                &newSD)) {
             _tprintf(TEXT("SetFileSecurity() failed. Error %d\n"), 
                   GetLastError());
             __leave;
          }

          fResult = TRUE;

       } __finally {

          // 
          // STEP 21: 释放已分配的内存,以免Memory Leak
          // 
          if (pUserSID)  myheapfree(pUserSID);
          if (szDomain)  myheapfree(szDomain);
          if (pFileSD) myheapfree(pFileSD);
          if (pNewACL) myheapfree(pNewACL);
       }

       return fResult;
    }

     

    int _tmain(int argc, TCHAR *argv[]) {

       if (argc < 3) {
          _tprintf(TEXT("usage: \"%s\" <FileName> <AccountName>\n"), argv[0]);
          return 1;
       }

       // argv[1] – 文件(目录)名
       // argv[2] – 用户(组)名
       // GENERIC_ALL表示所有的权限,其是一系列的NTFS权限的或
      
    //      NTFS的文件权限很细,还请参看MSDN
       if (!AddAccessRights(argv[1], argv[2], GENERIC_ALL)) {
          _tprintf(TEXT("AddAccessRights() failed.\n"));
          return 1;
       }
       else {
          _tprintf(TEXT("AddAccessRights() succeeded.\n"));
          return 0;
       }
    }





    三、             一些相关的API函数

     

    通过以上的示例,相信你已知道如何操作NTFS文件安全属性了,还有一些API函数需要介绍一下。

    1、  如果你要加入一个Access-Denied ACE,你可以使用AddAccessDeniedAce函数

    2、  如果你要删除一个ACE,你可以使用DeleteAce函数

    3、  如果你要检查你所设置的ACL是否合法,你可以使用IsValidAcl函数,同样,对于SD的合法也有一个叫IsValidSecurityDescriptor的函数

    4、  MakeAbsoluteSDMakeSelfRelativeSD两个函数可以在两种SD的格式中进行转换。

    5、  使用SetSecurityDescriptorDacl SetSecurityDescriptorSacl可以方便地把ACL设置到SD中。

    6、  使用GetSecurityDescriptorDacl or GetSecurityDescriptorSacl可以方便地取得SD中的ACL结构。

    我们把一干和SD/ACL/ACE相关的API函数叫作Low-Level Security Descriptor Functions,其详细信息还请参看MSDN

    我的MSNhaoel@hotmail.com,专栏在http://www.csdn.net/develop/author/netauthor/haoel/欢迎大家和我交流。

    <-上一页

    (版权所有,转载时请注明出处和作者信息)

    发表于 @ 2004年01月20日 21:19:00|评论(loading...)|编辑

    新一篇: 以程序的方式操纵NTFS的文件权限(上) | 旧一篇: C/C++内存问题检查利器—Purify (五)

    评论

    #fenglianghuai 发表于2004-08-10 17:51:00  IP: 221.10.41.*
    你好:

    谢谢楼主.看了你的文章受益匪浅.收藏.
    我用你的例子作了如下测试:
    AddAccessRights("e:\\2", "administrator", GENERIC_WRITE);发现高级中的"读取权限"也被允许了;
    我在"// STEP 9 如果文件(目录)"前加了addAccessDeniedAceEx,后去掉addAccessAllowedAceEx后测试:AddAccessRights("e:\\2", "administrator", GENERIC_WRITE);发现高级中的"读取权限"也被拒绝了。为了解决此问题我花了很长时间都无结果,在此向你求教。谢谢!!!!


    #fenglianghuai 发表于2004-08-10 17:53:00  IP: 221.10.41.*
    你好:

    谢谢楼主.看了你的文章受益匪浅.收藏.
    我用你的例子作了如下测试:
    AddAccessRights("e:\\2", "administrator", GENERIC_WRITE);发现高级中的"读取权限"也被允许了;
    我在"// STEP 9 如果文件(目录)"前加了addAccessDeniedAceEx,后去掉addAccessAllowedAceEx后测试:AddAccessRights("e:\\2", "administrator", GENERIC_WRITE);发现高级中的"读取权限"也被拒绝了。为了解决此问题我花了很长时间都无结果,在此向你求教。谢谢!!!!



    EMail:flhcd@163.com
    flhcd@yahoo.com.cn
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 陈皓