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