如何检查是否可以在MS XP / Vista上的给定目录中创建文件?

时间:2009-01-16 12:01:25

标签: python windows winapi windows-vista permissions

我有一个代码,用于在用户指定的目录中创建文件。用户可以指向他无法创建文件的目录,但他可以重命名。

我已经创建了用于测试目的的目录,我们称之为C:\foo

我拥有C:\foo的以下权限:

  • 遍历目录/执行文件
  • 删除子文件夹和文件
  • 卸下
  • 读取权限
  • 更改权限
  • 取得所有权

我对C:\foo没有以下任何权限:

  • 完全控制
  • 文件创建
  • 文件夹创建

到目前为止,我尝试了以下方法:


os.access('C:\foo', os.W_OK) == True

st = os.stat('C:\foo')
mode = st[stat.ST_MODE]
mode & stat.S_IWRITE == True

我认为这是因为我可以重命名文件夹,所以它对我来说是多变的。但它的内容 - 不是。

如果当前用户有权在该目录中创建文件,有谁知道如何编写将检查给定目录的代码?

简而言之 - 我想检查当前用户是否具有给定文件夹名称的文件创建文件夹创建权限。

编辑:需要此类代码来自“Certified for Windows Vista”计划的第3号测试案例,其中指出:

  
      
  1. 应用程序不得允许Least-Privileged用户将任何文件保存到Windows系统目录以传递此测试用例。
  2.   

这应该被理解为'应用程序可能会尝试在Windows系统目录中保存文件,但不应该在失败时崩溃吗?'或者更确切地说“应用程序必须在尝试保存文件之前执行安全检查?”

我是否应该因为Windows Vista本身不允许Least-Privileged用户保存%WINDIR%中的任何文件而停止打扰?

4 个答案:

答案 0 :(得分:4)

我不会浪费时间和LOC来检查权限。 Windows中文件创建的最终测试是创建本身。其他因素可能起作用(例如具有相同名称,磁盘空间和后台进程的现有文件(或更糟糕的是,文件夹)。这些条件甚至可以在您进行初始检查的时间和实际尝试创建的时间之间发生变化。文件。

所以,如果我有这样的场景,我会设计我的方法,以便在发生故障时不丢失任何数据,继续尝试创建我的文件,并为用户提供更改所选目录的选项如果创建失败,请再试一次。

答案 1 :(得分:4)

我最近编写了一个应用程序,通过一组测试来获取Microsoft的ISV状态,我也添加了这个条件。 我理解的方式是,如果用户是Least Priveledge,那么他将无权在系统文件夹中写入。所以我按照Ishmaeel描述的方式解决了这个问题。我尝试创建该文件并捕获异常,然后通知用户他没有权限将文件写入该目录。

根据我的理解,最不受特权限制的用户将没有必要的权限来写入这些文件夹,如果他有,那么他就不是Least-Priveledge用户。

  

我是否应该因为Windows Vista本身不允许Least-Privileged用户在%WINDIR%中保存任何文件而停止打扰?

在我看来?是。

答案 2 :(得分:3)

我同意其他答案,这样做的方法是尝试创建文件并捕获异常。

然而,在Vista上提防UAC!例如,参见"Why does my application allow me to save files to the Windows and System32 folders in Vista?":为了支持旧应用程序,Vista将“假装”创建文件,而实际上它在当前用户的配置文件下在所谓的虚拟存储中创建它。

要避免这种情况,您必须通过在.exe的清单中包含相应的命令来明确告诉Vista您不需要管理权限,请参阅上面链接的问题。

答案 3 :(得分:3)

import os
import tempfile

def can_create_file(folder_path):
    try:
        tempfile.TemporaryFile(dir=folder_path)
        return True
    except OSError:
        return False

def can_create_folder(folder_path):
    try:
        name = tempfile.mkdtemp(dir=folder_path)
        os.rmdir(name)
        return True
    except OSError:
        return False