Почему атрибут «только для чтения» устанавливается (иногда) для файлов, созданных моей службой? - PullRequest
1 голос
/ 11 сентября 2009

ПРИМЕЧАНИЕ. Это полное переписывание этого вопроса. Ранее я связывал некоторые проблемы ACL с проблемой, на которую я охотюсь, поэтому, вероятно, не было ответов.

У меня есть служба Windows, которая использует стандартные процедуры открытия / закрытия / записи для записи файла журнала (он читает данные из канала и вставляет их в журнал). Новый файл журнала открывается каждый день в полночь. Система Windows XP Embedded.

Служба работает как служба локальной системы (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 

Вот код, который я использую для открытия / создания файлов журнала:

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 (да, я знаю, он настолько устарел, что это не смешно. Пока вы не поймете, что мы только что перешли на XPE с NT 3.51).

Ответы [ 2 ]

4 голосов
/ 04 августа 2012

Реализация Microsoft open () имеет необязательный третий аргумент «pmode», который должен присутствовать, когда второй аргумент «oflag» включает флаг O_CREAT. Аргумент pmode указывает параметры доступа к файлу, которые устанавливаются при первом закрытии нового файла. Обычно вы передаете S_IREAD | S_IWRITE для pmode, приводящий к обычному файлу чтения / записи.

В вашем случае вы указали O_CREAT, но не указали третий аргумент, поэтому open () использовала любое значение в стеке в позиции третьего аргумента. Значение S_IWRITE равно 0x0080, поэтому, если значение в третьей позиции аргумента будет иметь очищенный бит 7, это приведет к файлу только для чтения. Тот факт, что вы получаете файл только для чтения только в некоторых случаях, согласуется с тем, что в качестве третьего аргумента передается нежелательная почта стека.

Ниже приведена ссылка на документацию по Visual Studio 2010 для open (). Этот аспект поведения функции не изменился со времен VC 6.

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

0 голосов
/ 17 сентября 2009

Ну, я понятия не имею, в чем заключается основная проблема с «открытыми» API в этом случае. Чтобы «исправить» проблему, я переключился на использование Win32 API для управления файлами (CreateFile, WriteFile, CloseHandle).

...