2009-09-11 3 views
1

ПРИМЕЧАНИЕ. Это полная перезапись этого вопроса. Раньше я сталкивался с некоторыми проблемами 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).

ответ

4

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

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

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

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

+0

Спасибо. Это здорово, наконец, получить правильный ответ. Я больше не работаю с этой компанией, поэтому я не могу легко вернуться и проверить этот бит кода, но я явно использовал «open» неправильно, поэтому я уверен, что вы правы. –

0

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