Page 1 sur 2
Protéger un fichier
Publié : mar. 17/mai/2005 12:17
par Jacobus
Salut,
Est-ce que quelqu'un connait le moyen d'empêcher la suppression d'un fichier, lorsqu'il n'est pas utilisé ?
Je cherche le moyen de protéger un fichier de prefs afin qu'il ne soit pas détruit, par accident ou volontairement. J'avoue que j'ai un doute sur cette possibilité, mais sait-on jamais.
J'ai bien imaginé des trucs tordus mais rien de concluant
Merci pour vos réponses et pistes éventuelles
@+ Jacobus
Publié : mar. 17/mai/2005 13:12
par Droopy
Tu peux faire ça avec des droits NFTS ( si OS >= NT4 )
ou le mieux serait de définir tes préférences dans la base de registre !
Publié : mar. 17/mai/2005 17:25
par gansta93
Sous windows 98, certains caractères ne sont pas reconnus par Explorer. Si tu utilise cette méthode, si tu fais juste del sur le fichier, le système dira qu'il n'existe pas.
Publié : mar. 17/mai/2005 22:07
par Le Soldat Inconnu
un fichier lecture seul ne suffit pas ?
tu peux enregistrer les param directement dans l'exe éventuellement, voir sur le forum, j'ai déjà fais un exemple
Publié : mer. 18/mai/2005 21:06
par KarLKoX
Il suffit d'ouvrir le fichier via
CreateFile en utilisant le flag FILE_ATTRIBUTE_READONLY.
Publié : jeu. 19/mai/2005 11:07
par Jacobus

Salut et merci pour vos réponses.
Pas simple de trouver une solution,
Donner l'attribut READONLY ne fait qu'empêcher la réécriture dans le fichier, mais rien contre la suppression du fichier. Un simple clic droit et supprimer l'envoie à la corbeille.
@KarlKoX, en effet sur MSDN il est précisé qu'avec createfile et l'attribut sus cité on ne peut accéder au fichier qu'en lecture seule, mais on peut le supprimer. A moins d'utiliser RAPI Functions =>
CeCreateFile(RAPI) où on aurait appliqué le flag FILE_ATTRIBUTE_READONLY
Le bean's, je ne sais pas comment accéder/utiliser cette fonction (RAPI)
CeCreateFile(RAPI) ni à quoi cela correspond exactement ?? Une nouvelle version de l'API sans doute ?
@Droopy, Merci pour ta Lib qui offre pas mal de possibilités et que j'utilise déjà, mais pour ce qui est du registre l'idée me séduit mais j'hésite à tester. En l'occurence, une variable contenue dans l'exe peut-elle être assimilée à une valeur enregistrable dans une clé ?
Le fichier de prefs contenant un nom unique qui ne doit jamais changer pour permettre le fonctionnement du prog.
Exemple :
Code : Tout sélectionner
Username$ = "Machin"
If Username$<>"Machin"
DeleteFile(Prog.exe) :EndIf
Je voudrais donc sauvegarder la valeur "Machin" à l'abri, car si un petit malin supprime le fichier de prefs contenant la dite valeur, et tente de recréer un fichier de prefs avec "Bidule" à la place, l'utilisateur principal sera très colère de plus retrouver son prog et ses données. D'où donc alors. Je sais, parfois j'ai la tête qui fume, mais ça c'est la pipe.
@LSI, Peut-être ta solution est-elle la mieux adaptée, je vais voir ce qu'il en est et tester la chose.
@Gansta93, Si ça marche que sur Win98, ça limite quand même...
Merci à tous, @+
Publié : jeu. 19/mai/2005 11:55
par KarLKoX
Non non, on ne peut pas supprimer le fichier s'il est ouvet avec le flag que j'ai cité, je viens de tester (tu m'as mis le doute) avec succes

Publié : jeu. 19/mai/2005 12:50
par Jacobus
Arf ! j'ai pourtant réussi à le supprimer (lorsqu'il n'est pas en cours d'utilisation). Je vais retester...
Publié : jeu. 19/mai/2005 13:22
par KarLKoX
Un exemple de ce que j'ai fait pour tester :
Code : Tout sélectionner
#GENERIC_READ = $80000000
#GENERIC_WRITE = $40000000
#FILE_SHARE_READ = $1
#FILE_SHARE_WRITE = $2
#CREATE_ALWAYS = 2
#CREATE_NEW = 1
#OPEN_ALWAYS = 4
#OPEN_EXISTING = 3
#TRUNCATE_EXISTING = 5
#FILE_ATTRIBUTE_ARCHIVE = $20
#FILE_ATTRIBUTE_HIDDEN = $2
#FILE_ATTRIBUTE_NORMAL = $80
#FILE_ATTRIBUTE_READONLY = $1
#FILE_ATTRIBUTE_SYSTEM = $4
#FILE_FLAG_DELETE_ON_CLOSE = $4000000
#FILE_FLAG_NO_BUFFERING = $20000000
#FILE_FLAG_OVERLAPPED = $40000000
#FILE_FLAG_POSIX_SEMANTICS = $1000000
#FILE_FLAG_RANDOM_ACCESS = $10000000
#FILE_FLAG_SEQUENTIAL_SCAN = $8000000
#FILE_FLAG_WRITE_THROUGH = $80000000
Procedure getch()
While Inkey() = ""
Delay(10)
Wend
EndProcedure
OpenConsole()
hFile = CreateFile_("c:\intel2.lic", #GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_READONLY, 0)
If (hFile = -1)
Debug "ERROR"
Else
PrintN("OK")
getch()
CloseConsole()
End
EndIf
Publié : jeu. 19/mai/2005 17:37
par nico
Pourquoi tu ne fais pas simple:
Tu crées deux fichiers, le premier tu le mets par exemple dans le répertoire c:\windows, c'est avec ce fichier que tu travailleras; le second tu le crées dans le répertoire de ton prog. Tu ne travailleras jamais avec le second fichier mais tu le mettras automatiquement à jour lorsque tu modifieras ton premier fichier et ne serviras finalement qu'à satisfaire la curiosité ou informer le possesseur du PC.
Les fichiers peuvent disposer de noms différents, de plus tu peux coder ton premier fichier qui ne sera donc pas une copie du second.

Publié : jeu. 19/mai/2005 20:08
par Jacobus
Prenons l'exemple suivant, qui devrait pourtant donner le résultat escompté. Le fichier créé de cette façon est effectivement en lecture seule mais reste effaçable, or le flag FILE_ATTRIBUTE_READONLY est utilisé.
Code : Tout sélectionner
Enumeration
#win_0
#btn_create
EndEnumeration
Procedure.s ApplicationDir()
appdir$ = Space(255)
GetCurrentDirectory_(255, @appdir$)
If Right(appdir$, 1) <> "\" ; si l'adresse ne finit pas par "\"
appdir$ = appdir$ + "\" ; on rajoute le "\"
EndIf
ProcedureReturn appdir$
EndProcedure
Global USERPASS$, DateCreated$, AppliDir$
DateCreated$ = "19/05/05"
AppliDir$=ApplicationDir()
Procedure Protect_INI()
If OpenPreferences("Protect.ini")=0
USERPASS$ = InputRequester("CHOIX D'UN MOT DE PASSE","Vous devez choisir un mot de passe :","")
EndIf
If USERPASS$ > ""
a$ = "Vous avez choisi le mot de passe suivant : " + Chr(10)
a$ + USERPASS$
If CreatePreferences("Protect.ini")
WritePreferenceString("USERPASS",USERPASS$)
WritePreferenceString("DATE",DateCreated$)
ClosePreferences()
EndIf
buffer.s = Space(#MAX_PATH)
buffer.s = AppliDir$+"Protect.ini"; créé dans répertoire courant
SetFileAttributes_(@buffer.s,#FILE_ATTRIBUTE_READONLY)
Else
a$ = "Vous n'avez choisi aucun mot de passe !"+Chr(13)+"Vous ne pouvez continuer."
MessageRequester("Information",a$,64)
End
EndIf
MessageRequester("Information",a$,64)
EndProcedure
Procedure fenetre()
If OpenPreferences("Protect.ini")<>0
USERPASS$ = ReadPreferenceString ("USERPASS", "")
DateCreated$ = ReadPreferenceString ("DATE", "")
Else
Protect_INI()
EndIf
ClosePreferences()
If OpenWindow(#win_0,0,0,200,100, #PB_Window_SystemMenu| #PB_Window_ScreenCentered |#PB_Window_TitleBar, "Test Protect ini") And CreateGadgetList(WindowID(#win_0))
ButtonGadget(#btn_create, 70, 40, 60, 20, "Creer ini")
EndIf
EndProcedure
fenetre()
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_EventGadget
Select EventGadgetID()
Case #btn_create : Protect_INI()
EndSelect
Case #PB_Event_CloseWindow : Quitter = 1
EndSelect
Until Quitter
End
Je ne dois pas l'utiliser correctement...
@ KarlKoX, Avec ton exemple en mode console j'obtiens ERROR...
@Nico, l'idée me plaît bien, on peut même en mettre partout de cette façon et en activer un seul...
@+
Publié : ven. 20/mai/2005 1:08
par KarLKoX
Je ne vois pas ou tu as utilisé l'API CreateFile comme je l'ai préconisé, je n'ai pas dit d'utiliser SetFileAttributes qui lui, permet la suppresion.
Voici ton code modifié fonctionnel :
Code : Tout sélectionner
#GENERIC_READ = $80000000
#GENERIC_WRITE = $40000000
#FILE_SHARE_READ = $1
#FILE_SHARE_WRITE = $2
#CREATE_ALWAYS = 2
#CREATE_NEW = 1
#OPEN_ALWAYS = 4
#OPEN_EXISTING = 3
#TRUNCATE_EXISTING = 5
#FILE_ATTRIBUTE_ARCHIVE = $20
#FILE_ATTRIBUTE_HIDDEN = $2
#FILE_ATTRIBUTE_NORMAL = $80
#FILE_ATTRIBUTE_READONLY = $1
#FILE_ATTRIBUTE_SYSTEM = $4
#FILE_FLAG_DELETE_ON_CLOSE = $4000000
#FILE_FLAG_NO_BUFFERING = $20000000
#FILE_FLAG_OVERLAPPED = $40000000
#FILE_FLAG_POSIX_SEMANTICS = $1000000
#FILE_FLAG_RANDOM_ACCESS = $10000000
#FILE_FLAG_SEQUENTIAL_SCAN = $8000000
#FILE_FLAG_WRITE_THROUGH = $80000000
Enumeration
#win_0
#btn_create
EndEnumeration
Global m_handle.l
Procedure.s ApplicationDir()
appdir$ = Space(255)
GetCurrentDirectory_(255, @appdir$)
If Right(appdir$, 1) <> "\" ; si l'adresse ne finit pas par "\"
appdir$ = appdir$ + "\" ; on rajoute le "\"
EndIf
ProcedureReturn appdir$
EndProcedure
Global USERPASS$, DateCreated$, AppliDir$
DateCreated$ = "19/05/05"
AppliDir$=ApplicationDir()
Procedure LockFile(fullpath.s)
hFile = CreateFile_(fullpath,#GENERIC_READ, #FILE_SHARE_READ, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_READONLY, 0)
ProcedureReturn hFile
EndProcedure
Procedure UnLockFile(handle)
CloseHandle_(handle)
EndProcedure
Procedure Protect_INI()
If OpenPreferences("Protect.ini")=0
USERPASS$ = InputRequester("CHOIX D'UN MOT DE PASSE","Vous devez choisir un mot de passe :","")
EndIf
If USERPASS$ > ""
a$ = "Vous avez choisi le mot de passe suivant : " + Chr(10)
a$ + USERPASS$
If CreatePreferences("Protect.ini")
WritePreferenceString("USERPASS",USERPASS$)
WritePreferenceString("DATE",DateCreated$)
ClosePreferences()
EndIf
buffer.s = Space(#MAX_PATH)
buffer.s = AppliDir$+"Protect.ini"; créé dans répertoire courant
SetFileAttributes_(@buffer.s,#FILE_ATTRIBUTE_READONLY)
m_handle = LockFile(buffer)
Else
a$ = "Vous n'avez choisi aucun mot de passe !"+Chr(13)+"Vous ne pouvez continuer."
MessageRequester("Information",a$,64)
End
EndIf
MessageRequester("Information",a$,64)
EndProcedure
Procedure fenetre()
If OpenPreferences("Protect.ini")<>0
USERPASS$ = ReadPreferenceString ("USERPASS", "")
DateCreated$ = ReadPreferenceString ("DATE", "")
Else
Protect_INI()
EndIf
ClosePreferences()
If OpenWindow(#win_0,0,0,200,100, #PB_Window_SystemMenu| #PB_Window_ScreenCentered |#PB_Window_TitleBar, "Test Protect ini") And CreateGadgetList(WindowID(#win_0))
ButtonGadget(#btn_create, 70, 40, 60, 20, "Creer ini")
EndIf
EndProcedure
fenetre()
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_EventGadget
Select EventGadgetID()
Case #btn_create : Protect_INI()
EndSelect
Case #PB_Event_CloseWindow : Quitter = 1
EndSelect
Until Quitter
UnLockFile(m_handle)
End
Publié : ven. 20/mai/2005 20:11
par Jacobus
Et avec ce code, tel quel, tu obtiens un fichier que tu ne peux supprimer ?
Parce que moi non. Et si on commente SetFileAttributes_ le fichier créé a l'attribut NORMAL. J'ai donc réessayé de plusieurs façons mais sans succès.
Dans la partie suivante, et de cette manière, ta procédure aurait dû retourner un fichier en lecture seule, mais non, rien d'autre qu'un attribut normal...je sèche.
Code : Tout sélectionner
If CreatePreferences("Protect.ini")
WritePreferenceString("USERPASS",USERPASS$)
WritePreferenceString("DATE",DateCreated$)
ClosePreferences()
EndIf
ProtectFile.s = AppliDir$+"Protect.ini"; dans répertoire courant
m_handle = LockFile(ProtectFile)
Publié : ven. 20/mai/2005 20:17
par KarLKoX
Je sais pas mais chez moi, impossible de supprimer le fichier, tant que l'éxécutable est lancé en tout cas.
Je vois vraiement pas pourquoi ca ne marche pas chez toi, peut être un problème de droit (possible sur une partition ntfs)
Publié : ven. 20/mai/2005 21:06
par Jacobus
Ok, là on tombe d'accord, tant que l'exécutable est lancé on ne peut supprimer le fichier qui est en cours d'utilisation.
Je pensais qu'il était possible de protéger un fichier contre la suppression lorsqu'il n'est pas utilisé. Simplement stocké sur un lecteur ou autre et avec un attribut lui permettant de ne pas être effacé.
Merci quand même pour tes efforts. Avec l'idée de Nico que je vais pousser un peu plus loin, je pense avoir trouvé le moyen de remèdier à cela avec la méthode des poupées gigognes. C'est un peu vicelard mais ça devrait faire l'affaire.
Merci et @+