3

注: これは、この質問を完全に書き直したものです。私は以前、いくつかの ACL の問題を私が探している問題と混同していました。それがおそらく答えがなかった理由です。

標準のオープン/クローズ/書き込みルーチンを使用してログ ファイルを書き込む Windows サービスがあります (パイプからデータを読み取り、ログに記録します)。毎日午前 0 時に新しいログ ファイルが開かれます。システムは Windows XP Embedded です。

このサービスは、ローカル システム サービス (ユーザーに対して NULL を指定した CreateService) として実行されます。

サービスが最初に起動すると、ログ ファイルが作成され、問題なく書き込まれます。この時点ですべて問題なく、サービス (ま​​たはコンピューター) を問題なく再起動できます。

ただし、真夜中 (日が変わるとき) に、サービスは新しいログ ファイルを作成し、それに書き込みます。面白いことに、この新しいログ ファイルには「読み取り専用」フラグが設定されています。サービス (ま​​たはコンピューター) が再起動すると、サービスは書き込み用にファイルを開くことができなくなるため、これは問題です。

問題がすでに発生しているシステムからの関連情報は次のとおりです。

 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;
}

ファイルが読み取り専用フラグを取得する方法を理解するのに本当に苦労しています。手がかりや方向性を教えてくれる人は誰でも、大歓迎です。

コンパイラは VC 6 です (ええ、わかっています。時代遅れなので面白くありません。NT 3.51 から XPE にアップグレードしたばかりであることに気付くまでは)。

4

2 に答える 2

6

open() の Microsoft 実装には、オプションの 3 番目の引数 'pmode' があります。これは、2 番目の引数 'oflag' に O_CREAT フラグが含まれている場合に必要です。pmode 引数は、新しいファイルが初めて閉じられるときに設定されるファイル許可設定を指定します。通常、S_IREAD | を渡します。pmode の S_IWRITE。通常の読み取り/書き込みファイルになります。

あなたの場合、O_CREAT を指定しましたが、3 番目の引数を省略したため、open() は 3 番目の引数の位置でたまたまスタックにあった値を使用しました。S_IWRITE の値は 0x0080 であるため、第 3 引数位置の値のビット 7 がクリアされていると、読み取り専用ファイルになります。たまにしか読み取り専用ファイルを取得しないという事実は、スタック ジャンクが 3 番目の引数として渡されることと一致しています。

以下は、open() の Visual Studio 2010 ドキュメントへのリンクです。関数の動作のこの側面は、VC 6 以降変更されていません。

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

于 2012-08-04T16:24:52.533 に答える
0

この場合、「オープン」API の根本的な問題が何であるかはわかりません。問題を「修正」するために、最終的にファイル管理に Win32 API (CreateFile、WriteFile、CloseHandle) を使用するように切り替えました。

于 2009-09-16T20:16:43.193 に答える