2009-09-11 7 views
1

NOTE: Ceci est une réécriture complète de cette question. J'avais précédemment confondu quelques problèmes d'ACL avec le problème que je suis en train de chasser, ce qui explique probablement pourquoi il n'y avait pas de réponses.Pourquoi l'attribut en lecture seule est-il défini (parfois) pour les fichiers créés par mon service?

J'ai un service Windows qui utilise les routines standard d'ouverture/fermeture/écriture pour écrire un fichier journal (il lit les données d'un tube et les insère dans le journal). Un nouveau fichier journal est ouvert chaque jour à minuit. Le système est Windows XP Embedded.

Le service s'exécute en tant que service Système local (CreateService avec NULL pour l'utilisateur). Lorsque le service démarre initialement, il crée un fichier journal et y écrit sans problème. À ce stade tout est OK, et vous pouvez redémarrer le service (ou l'ordinateur) sans problèmes.

Toutefois, à minuit (lorsque le jour change), le service crée un nouveau fichier journal et y écrit. La chose amusante est, ce nouveau fichier journal a le jeu d'indicateurs «lecture seule». C'est un problème car si le service (ou l'ordinateur) redémarre, le service ne peut plus ouvrir le fichier en écriture.

Voici les informations pertinentes du système avec le problème ayant déjà eu lieu:

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 

Voici le code que j'utilise pour ouvrir/créer les fichiers journaux:

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

J'ai réel difficulté à comprendre comment le fichier obtient ce drapeau en lecture seule. Toute personne qui peut me donner une idée ou une direction, je l'apprécierais grandement.

Le compilateur est VC 6 (Oui, je sais, c'est tellement dépassé que ce n'est pas drôle, jusqu'à ce que vous vous rendiez compte que nous venons tout juste de passer de NT 3.51 à XPE).

Répondre

4

L'implémentation Microsoft de open() a un troisième argument facultatif 'pmode', qui doit être présent lorsque le second argument 'oflag' inclut l'indicateur O_CREAT. L'argument pmode spécifie les paramètres d'autorisation de fichier, qui sont définis lorsque le nouveau fichier est fermé pour la première fois. Typiquement, vous passeriez S_IREAD | S_IWRITE pour pmode, résultant dans un fichier de lecture/écriture ordinaire.

Dans votre cas, vous avez spécifié O_CREAT mais vous avez omis le troisième argument, open() a donc utilisé la valeur qui se trouvait sur la pile à la troisième position d'argument. La valeur de S_IWRITE est 0x0080, donc si la valeur dans la troisième position d'argument avait le bit 7 clair, il en résulterait un fichier en lecture seule. Le fait que vous ayez un fichier en lecture seule seulement une partie du temps, est cohérent avec l'empilement de pile qui est passé comme le troisième argument.

Voici le lien pour la documentation de Visual Studio 2010 pour open(). Cet aspect du comportement de la fonction n'a pas changé depuis VC 6.

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

+0

Merci. C'est génial d'avoir enfin la bonne réponse. Je ne suis plus avec cette compagnie, donc je ne peux pas facilement revenir en arrière et vérifier sur ce morceau de code, mais j'ai clairement utilisé «ouvert» incorrectement, donc je parie que vous avez raison. –

0

Eh bien, je n'ai aucune idée de ce que le problème sous-jacent est avec les API 'ouvertes' dans ce cas. Afin de 'réparer' le problème, j'ai fini par passer à l'utilisation des API Win32 pour la gestion des fichiers (CreateFile, WriteFile, CloseHandle).