代码之家  ›  专栏  ›  技术社区  ›  Michael Kohne

为什么(有时)为我的服务创建的文件设置只读属性?

  •  4
  • Michael Kohne  · 技术社区  · 16 年前

    注意:这是对这个问题的完整重写。我之前曾将一些ACL问题与我正在寻找的问题混为一谈,这可能是没有答案的原因。

    我有一个windows服务,它使用标准的打开/关闭/写入例程来写入日志文件(它从管道中读取内容并将其写入日志)。每天午夜都会打开一个新的日志文件。该系统为Windows XP嵌入式系统。

    当服务最初启动时,它会创建一个日志文件并写入其中,没有任何问题。此时一切正常,您可以毫无问题地重新启动服务(或计算机)。

     Directory of C:\bbbaudit
    
    09/16/2009  12:00 AM    <DIR>          .
    09/16/2009  12:00 AM    <DIR>          ..
    09/16/2009  12:00 AM               437 AU090915.ADX
    09/16/2009  12:00 AM                62 AU090916.ADX
    
    attrib c:\bbbaudit\*
    A          C:\bbbaudit\AU090915.ADX <-- old log file (before midnight)
    A    R     C:\bbbaudit\AU090916.ADX <-- new log file (after midnight)
    
    cacls output:
    C:\ BUILTIN\Administrators:(OI)(CI)F 
        NT AUTHORITY\SYSTEM:(OI)(CI)F 
        CREATOR OWNER:(OI)(CI)(IO)F 
        BUILTIN\Users:(OI)(CI)R 
        BUILTIN\Users:(CI)(special access:)
                          FILE_APPEND_DATA
    
        BUILTIN\Users:(CI)(IO)(special access:)
                              FILE_WRITE_DATA
    
        Everyone:R 
    
    C:\bbbaudit BUILTIN\Administrators:(OI)(CI)F 
                NT AUTHORITY\SYSTEM:(OI)(CI)F 
                CFN3\Administrator:F 
                CREATOR OWNER:(OI)(CI)(IO)F 
    

    以下是我用来打开/创建日志文件的代码:

    static int open_or_create_file(char *fname, bool &alreadyExists)
    {
      int fdes;
    
      // try to create new file, fail if it already exists
      alreadyExists = false;
      fdes = open(fname, O_WRONLY | O_APPEND | O_CREAT | O_EXCL);
      if (fdes < 0)
      {
        // try to open existing, don't create new file
        alreadyExists = true;
        fdes = open(fname, O_WRONLY | O_APPEND);
      }
    
      return fdes;
    }
    

    2 回复  |  直到 16 年前
        1
  •  6
  •   cdev    13 年前

    在您的例子中,您指定了O_CREAT,但省略了第三个参数,因此open()使用了堆栈中第三个变量位置的任何值。S_IWRITE的值为0x0080,因此,如果第三个参数位置的值恰好有位7清除,则会导致文件为只读。事实上,你只在某些时候得到一个只读文件,这与作为第三个参数传递的堆栈垃圾是一致的。

    下面是Visual Studio 2010 open()文档的链接。自VC 6以来,函数行为的这一方面没有改变。

    http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx

        2
  •  0
  •   Michael Kohne    16 年前

    好吧,在这种情况下,我不知道“开放”API的根本问题是什么。为了“修复”这个问题,我最终切换到使用Win32 API进行文件管理(CreateFile、WriteFile、CloseHandle)。