Pourquoi l'attribut en lecture seule est-il défini (parfois) pour les fichiers créés par mon service?

StackOverflow https://stackoverflow.com/questions/1412625

  •  06-07-2019
  •  | 
  •  

Question

NOTE: Ceci est une réécriture complète de cette question. J'avais déjà associé certains problèmes de LCA au problème que je cherchais, ce qui explique probablement pourquoi il n'y a pas eu de réponses.

J'ai un service Windows qui utilise les routines standard d'ouverture / fermeture / écriture pour écrire un fichier journal (il lit les éléments d'un tuyau et les enregistre 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 la valeur NULL pour l'utilisateur).

Lorsque le service démarre pour la première fois, il crée un fichier journal et l’écrit sans aucun problème. À ce stade, tout est en ordre et vous pouvez redémarrer le service (ou l'ordinateur) sans problème.

Cependant, à minuit (lorsque le jour change), le service crée un nouveau fichier journal et l’écrit. Ce qui est amusant, c’est que ce nouveau fichier journal a le drapeau «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 à l'origine du problème:

 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 vraiment du mal à comprendre comment le fichier reçoit ce drapeau en lecture seule. Quiconque peut me donner un indice ou une direction, je l'apprécierais grandement.

Le compilateur est VC 6 (oui, je sais, il est tellement obsolète que ce n’est pas drôle. Tant que vous ne réaliserez pas que nous venons de passer à XPE à partir de NT 3.51).

Était-ce utile?

La solution

L'implémentation Microsoft de open () a un troisième argument facultatif, 'pmode', qui doit être présent lorsque le deuxième argument, 'oflag', inclut l'indicateur O_CREAT. L'argument pmode spécifie les paramètres d'autorisation de fichier, définis lors de la première fermeture du nouveau fichier. En général, vous passeriez S_IREAD | S_IWRITE pour pmode, résultant en un fichier en lecture / écriture ordinaire.

Dans votre cas, vous avez spécifié O_CREAT mais omis le troisième argument. Open () a donc utilisé la valeur quelle que soit la valeur de la pile à la troisième position de l'argument. La valeur de S_IWRITE est 0x0080. Par conséquent, si la valeur du troisième argument a le bit 7 vide, le fichier en lecture seule en résulterait. Le fait que vous n'obteniez qu'un fichier en lecture seule de temps en temps est cohérent avec le fait que la jonque de pile soit passée en tant que troisième argument.

Vous trouverez ci-dessous le lien vers 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

Autres conseils

Eh bien, je n'ai aucune idée du problème sous-jacent aux API "ouvertes" dans ce cas. Afin de "résoudre" le problème, j'ai finalement décidé d'utiliser les API Win32 pour la gestion de fichiers (CreateFile, WriteFile, CloseHandle).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top