Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 为什么对我的服务创建的文件设置只读属性(有时)?_Windows_Acl - Fatal编程技术网

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

Windows 为什么对我的服务创建的文件设置只读属性(有时)?,windows,acl,Windows,Acl,注:这是对这个问题的完整重写。我之前将一些ACL问题与我正在寻找的问题混为一谈,这可能就是为什么没有答案的原因 我有一个windows服务,它使用标准的打开/关闭/写入例程来写入日志文件(它从管道中读取内容并将其填充到日志中)。每天午夜打开一个新的日志文件。该系统是Windows XP嵌入式系统 该服务作为本地系统服务运行(CreateService,用户为NULL) 当服务最初启动时,它会创建一个日志文件,并毫无问题地写入其中。此时一切正常,您可以重新启动服务(或计算机),而不会出现任何问题

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

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

该服务作为本地系统服务运行(CreateService,用户为NULL)

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

但是,在午夜(白天变化时),服务会创建一个新的日志文件并写入其中。有趣的是,这个新日志文件设置了“只读”标志。这是一个问题,因为如果服务(或计算机)重新启动,服务将无法再打开文件进行写入

以下是已发生问题的系统的相关信息:

 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 
C:\bbbaudit的
目录
09/16/2009上午12:00。
2009年9月16日上午12:00。。
09/16/2009 12:00 AM 437 AU090915.ADX
09/16/2009 12:00 AM 62 AU090916.ADX
属性c:\bbbaudit\*

A C:\bbbaudit\AU090915.ADX嗯,我不知道在这种情况下“开放”API的潜在问题是什么。为了“修复”这个问题,我最终切换到使用Win32 API进行文件管理(CreateFile、WriteFile、CloseHandle)。

open()的Microsoft实现有一个可选的第三个参数“pmode”,当第二个参数“oflag”包含O_CREAT标志时,需要出现该参数。pmode参数指定文件权限设置,这些设置是在第一次关闭新文件时设置的。通常,您会将S|IREAD | S|IWRITE传递给pmode,从而生成一个普通的读/写文件

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

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


谢谢。终于得到了正确的答案真是太好了。我已经不在那家公司工作了,所以我不能轻易地回去验证这段代码,但我显然没有正确地使用“open”,所以我打赌你是正确的。在VC2019中仍然是一样的
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;
}