Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Info bug instable VB6

7 réponses
Avatar
Christian Hubert-Hugoud / weabow - Xtrem7
Bonjour à tous,

Je viens d'avoir une quantité de problèmes sur un freeware. Je vous fais ce
retour car le bug n'est pas facile à localiser, car dépendant directement de
la machine.

Il est dans la valeur de retour de GetAtt. Suivant les machines (quelque
soit l'OS), cette fonction renvoie des valeurs "artistiques", aléatoirement
(un coup bon, un coup faux, mais toujours sur les mêmes fichiers), et du
coup impossibles à utiliser avec le SetAtt.

Hope this helps

Christian

7 réponses

Avatar
Gloops
Bonjour,

Il semblerait que quelqu'un ait déjà constaté quelque chose de semb lable ...

http://www.codeguru.com/forum/archive/index.php/t-20841.html

ça remonte à 2001.
________________________________________________________________________
Christian Hubert-Hugoud / weabow - Xtrem7 a écrit, le 14/10/2009 09:07 :
Bonjour à tous,

Je viens d'avoir une quantité de problèmes sur un freeware. Je vous fais
ce retour car le bug n'est pas facile à localiser, car dépendant
directement de la machine.

Il est dans la valeur de retour de GetAtt. Suivant les machines (quelqu e
soit l'OS), cette fonction renvoie des valeurs "artistiques",
aléatoirement (un coup bon, un coup faux, mais toujours sur les mêm es
fichiers), et du coup impossibles à utiliser avec le SetAtt.

Hope this helps

Christian



Avatar
Christian Hubert-Hugoud / weabow - Xtrem7
Avatar
Jean-Marc
On 14 oct, 10:41, "Christian Hubert-Hugoud / weabow - Xtrem7"
wrote:
Bien vu



Hello,
c'est en effet un "bug" qui se manifeste essentiellement sous
Windows2000.

Bug? Pas si sur, en fait.

Sous Windows 2000, si je fais un GetAttr() sur hiberfile.sys ou
pageFile.sys (par exemple), j'obtiens effectivement une Error 5.

Pour aller plus loin, je fais donc en C cette fois un GetFileAttributes
(); celui ci me renvoie comme valeur d'attribut
"INVALID_FILE_ATTRIBUTES" (-1);
Si derrière je fais un GetLastError(), j'obtiens 0x20 :
ERROR_SHARING_VIOLATION:
"The process cannot access the file because it is being used by
another process."

On a donc l'explication: La fonction VB GetAttr appelle la fonction de
l'API Windows correspondante (GetFileAttributes) qui elle même répond
par une erreur - Tout logiquement, VB renvoie à son tour une erreur -
Le fait que GetFileAttributes ne puisse pas s'exécuter sur
Hiberfil.sys sous Windows 2000 est discutable, mais ne me choque pas:
qu'on ne puisse obtenir les attributes d'un fichier système/caché/etc.
ne me semble pas grave.

Coté VB, on pourrait discuter sur la pertinence de renvoyer une Erreur
5 : Invalid procedure call or argument, mais pourquoi pas: cette
valeur en vaut une autre.

Moralité: il ne reste plus qu'à écrire une fonction au dessus de
GetAttr() avec un On error Goto qui va bien pour trapper les erreurs
et modifier le code appellant pour trapper les erreurs éventuelles et
ne pas s'en émouvoir.

Pour ma part, je en vois pas ça comme un "bug VB": c'est juste une
limite de GetAttr, directement héritée d'une limite de l'API Windows.

Cordialement;

--
Jean-Marc
Avatar
Christian Hubert-Hugoud / weabow - Xtrem7
Superbe explication, en fait.

Là où je te suis moins est que ce bug remonte aussi sur Vista sur un fichier
html tout à fait standard... alors que les autres fichiers du même
répertoire sont biens évalués.

Effectivement une solution consiste à trapper l'erreur.

En tous cas bravo pour ta disponibilité.

Christian

"Jean-Marc" a écrit dans le message de
news:
On 14 oct, 10:41, "Christian Hubert-Hugoud / weabow - Xtrem7"
wrote:
Bien vu



Hello,
c'est en effet un "bug" qui se manifeste essentiellement sous
Windows2000.

Bug? Pas si sur, en fait.

Sous Windows 2000, si je fais un GetAttr() sur hiberfile.sys ou
pageFile.sys (par exemple), j'obtiens effectivement une Error 5.

Pour aller plus loin, je fais donc en C cette fois un GetFileAttributes
(); celui ci me renvoie comme valeur d'attribut
"INVALID_FILE_ATTRIBUTES" (-1);
Si derrière je fais un GetLastError(), j'obtiens 0x20 :
ERROR_SHARING_VIOLATION:
"The process cannot access the file because it is being used by
another process."

On a donc l'explication: La fonction VB GetAttr appelle la fonction de
l'API Windows correspondante (GetFileAttributes) qui elle même répond
par une erreur - Tout logiquement, VB renvoie à son tour une erreur -
Le fait que GetFileAttributes ne puisse pas s'exécuter sur
Hiberfil.sys sous Windows 2000 est discutable, mais ne me choque pas:
qu'on ne puisse obtenir les attributes d'un fichier système/caché/etc.
ne me semble pas grave.

Coté VB, on pourrait discuter sur la pertinence de renvoyer une Erreur
5 : Invalid procedure call or argument, mais pourquoi pas: cette
valeur en vaut une autre.

Moralité: il ne reste plus qu'à écrire une fonction au dessus de
GetAttr() avec un On error Goto qui va bien pour trapper les erreurs
et modifier le code appellant pour trapper les erreurs éventuelles et
ne pas s'en émouvoir.

Pour ma part, je en vois pas ça comme un "bug VB": c'est juste une
limite de GetAttr, directement héritée d'une limite de l'API Windows.

Cordialement;

--
Jean-Marc
Avatar
Gloops
Ah, je suis désolé de ne pas avoir tilté, j'ai un programme de purg e de
fichiers temporaires, là-dessus je commence par retirer l'attribut
lecture seule (sauf si l'utilisateur a décoché la case correspondante ),
et jusque là ça se passait sans problème.

Hier, j'ai eu une erreur au niveau de la lecture des attributs.
Je n'ai pas spécialement cherché à comprendre, j'ai mis une gestion
d'erreur et puis fini. Effectivement, l'erreur s'est produite quand
l'antivirus bloquait le fichier au moment où je cherchais à lire ses
attributs. Dans ce cas précis ça ne pose pas de problème puisque le
fichier finit bel et bien par disparaître, donc que ce soit le programm e
de purge ou l'antivirus qui le fasse ...

Nous avons donc l'explication grâce à Jean-Marc (et c'est vrai que si
j'avais été plus réveillé j'avais l'occasion de le dire) : il est
impossible d'évaluer les attributs d'un fichier verrouillé.
________________________________________
Jean-Marc a écrit, le 14/10/2009 16:01 :
On 14 oct, 10:41, "Christian Hubert-Hugoud / weabow - Xtrem7"
wrote:
Bien vu



Hello,
c'est en effet un "bug" qui se manifeste essentiellement sous
Windows2000.

Bug? Pas si sur, en fait.

Sous Windows 2000, si je fais un GetAttr() sur hiberfile.sys ou
pageFile.sys (par exemple), j'obtiens effectivement une Error 5.

Pour aller plus loin, je fais donc en C cette fois un GetFileAttributes
(); celui ci me renvoie comme valeur d'attribut
"INVALID_FILE_ATTRIBUTES" (-1);
Si derrière je fais un GetLastError(), j'obtiens 0x20 :
ERROR_SHARING_VIOLATION:
"The process cannot access the file because it is being used by
another process."

On a donc l'explication: La fonction VB GetAttr appelle la fonction de
l'API Windows correspondante (GetFileAttributes) qui elle même répo nd
par une erreur - Tout logiquement, VB renvoie à son tour une erreur -
Le fait que GetFileAttributes ne puisse pas s'exécuter sur
Hiberfil.sys sous Windows 2000 est discutable, mais ne me choque pas:
qu'on ne puisse obtenir les attributes d'un fichier système/caché/e tc.
ne me semble pas grave.

Coté VB, on pourrait discuter sur la pertinence de renvoyer une Erreu r
5 : Invalid procedure call or argument, mais pourquoi pas: cette
valeur en vaut une autre.

Moralité: il ne reste plus qu'à écrire une fonction au dessus de
GetAttr() avec un On error Goto qui va bien pour trapper les erreurs
et modifier le code appellant pour trapper les erreurs éventuelles et
ne pas s'en émouvoir.

Pour ma part, je en vois pas ça comme un "bug VB": c'est juste une
limite de GetAttr, directement héritée d'une limite de l'API Window s.

Cordialement;

--
Jean-Marc




Avatar
Jean-marc
Christian Hubert-Hugoud / weabow - Xtrem7 wrote:
Superbe explication, en fait.

Là où je te suis moins est que ce bug remonte aussi sur Vista sur un
fichier html tout à fait standard... alors que les autres fichiers du
même répertoire sont biens évalués.

Effectivement une solution consiste à trapper l'erreur.

En tous cas bravo pour ta disponibilité.



Hello,

en effet, le problème peut survenir pour diverses raisons, la plus courante
étant l'accès à un fichier temporairement (ou non) protégé car partagé.

Comme je le disais dans mon post précédent, on peut s'en sortir en
trappant l'erreur dans VB, mais on manque alors l'information concernant la
vraie cause de l'erreur.

Finalement, une façon élégante de réler le problème consiste
à se définir sa propre fonction de lecture d'attributs et de faire en sorte
qu'elle remonte proprement l'erreur (pour info) si il y en a une.

Le plus simple et le plus naturel est de faire la fonction en C, de la
mettre dans une Dll et de l'appeler coté VB.

J'ai mis en ligne un petit fichier zip contenant la dll (avec les sources)
et
un programme d'exemple en VB :
http://users.skynet.be/candide/getattr.html

Le code source de la dll est très court :

#include<stdio.h>
#include<stdlib.h>

#include<windows.h>

#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)

#define export __declspec (dllexport)

export long __stdcall GetAttributes(LPCSTR pszString, long *attr, long
*errCode)
{
long loc_attr = 0L;
long ret = 0L;

loc_attr = GetFileAttributes(pszString);

if(loc_attr == INVALID_FILE_ATTRIBUTES)
{
*errCode = GetLastError();
*attr = loc_attr;
ret = 0L;
}
else
{
*errCode = 0;
*attr = loc_attr;
ret = 1L;
}

return ret;
}

La fonction retourne 1 en cas de succès, 0 sinon.
Quand elle retourne 1, l'attribut de fichier est mis dans attr.
Quand elle retourne 0, le code d'erreur est renseigné dans errCode

[note: pour ceux qui veulent en savoir plus sur la création de
dll et l'utilisation en VB, voir la FAQ:
http://faq.vb.free.fr/index.php?question4

L'utilisation en VB est toute simple :

Option Explicit

Private Declare Function GetAttributes _
Lib "clibattr.dll" Alias "" _
(ByVal s As String, attr As Long, errCode As Long)
As Long


Dim s As String
Dim ret As Long
Dim attr As Long
Dim errCode As Long


s = "c:IO.SYS"

ret = GetAttributes(s, attr, errCode)

If ret = 1 Then
' function succeeds
MsgBox "Attributes for file: " & s & " : " & attr & vbCrLf & _
"Text Attr = " & GetAttrStringFromAttr(attr)

Else
' function fails
MsgBox "Error getting attributes for file " & s & vbCrLf & _
"Error code from GetFileAttributes : " & errCode
End If


Et pour obtenir les attributs en clair :

' cf http://msdn.microsoft.com/en-us/library/ee332330(VS.85).aspx

Const FILE_ATTRIBUTE_READONLY As Long = &H1
Const FILE_ATTRIBUTE_HIDDEN As Long = &H2
Const FILE_ATTRIBUTE_SYSTEM As Long = &H4
Const FILE_ATTRIBUTE_DIRECTORY As Long = &H10
Const FILE_ATTRIBUTE_ARCHIVE As Long = &H20
Const FILE_ATTRIBUTE_DEVICE As Long = &H40
Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Const FILE_ATTRIBUTE_TEMPORARY As Long = &H100
Const FILE_ATTRIBUTE_SPARSE_FILE As Long = &H200
Const FILE_ATTRIBUTE_REPARSE_POINT As Long = &H400
Const FILE_ATTRIBUTE_COMPRESSED As Long = &H800
Const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED As Long = &H2000
Const FILE_ATTRIBUTE_OFFLINE As Long = &H1000
Const FILE_ATTRIBUTE_ENCRYPTED As Long = &H4000
Const FILE_ATTRIBUTE_VIRTUAL As Long = &H10000

et la fonction qui va avec :

Private Function GetAttrStringFromAttr(ByVal attr As Long) As String
Dim szAttr As String

If attr And FILE_ATTRIBUTE_READONLY Then
szAttr = szAttr & "READONLY" & "."
End If
If attr And FILE_ATTRIBUTE_HIDDEN Then
szAttr = szAttr & "HIDDEN" & "."
End If
If attr And FILE_ATTRIBUTE_SYSTEM Then
szAttr = szAttr & "SYSTEM" & "."
End If
If attr And FILE_ATTRIBUTE_DIRECTORY Then
szAttr = szAttr & "DIRECTORY" & "."
End If
If attr And FILE_ATTRIBUTE_ARCHIVE Then
szAttr = szAttr & "ARCHIVE" & "."
End If
If attr And FILE_ATTRIBUTE_DEVICE Then
szAttr = szAttr & "DEVICE" & "."
End If
If attr And FILE_ATTRIBUTE_NORMAL Then
szAttr = szAttr & "NORMAL" & "."
End If
If attr And FILE_ATTRIBUTE_TEMPORARY Then
szAttr = szAttr & "TEMPORARY" & "."
End If

If attr And FILE_ATTRIBUTE_SPARSE_FILE Then
szAttr = szAttr & "SPARSE_FILE" & "."
End If
If attr And FILE_ATTRIBUTE_REPARSE_POINT Then
szAttr = szAttr & "REPARSE_POINT" & "."
End If
If attr And FILE_ATTRIBUTE_COMPRESSED Then
szAttr = szAttr & "COMPRESSED" & "."
End If
If attr And FILE_ATTRIBUTE_NOT_CONTENT_INDEXED Then
szAttr = szAttr & "NOT_CONTENT_INDEXED" & "."
End If
If attr And FILE_ATTRIBUTE_OFFLINE Then
szAttr = szAttr & "OFFLINE" & "."
End If
If attr And FILE_ATTRIBUTE_ENCRYPTED Then
szAttr = szAttr & "ENCRYPTED" & "."
End If
If attr And FILE_ATTRIBUTE_VIRTUAL Then
szAttr = szAttr & "VIRTUAL" & "."
End If

GetAttrStringFromAttr = szAttr
End Function

Avec tout ça, on a une nouvelle fonction GetAttribute, qui ne plante
jamais et qui renseigne proprement les erreurs quand il y en a.

A noter : on trouvera la signification des codes d'erreurs retournés
dans errCode ici :
http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

Bonne soirée !


--
Jean-marc Noury (jean_marc_n2)
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;
Avatar
Christian Hubert-Hugoud / weabow - Xtrem7
Impressionnant !

"Jean-marc" a écrit dans le message de
news:4ad757b1$0$2858$
Christian Hubert-Hugoud / weabow - Xtrem7 wrote:
Superbe explication, en fait.

Là où je te suis moins est que ce bug remonte aussi sur Vista sur un
fichier html tout à fait standard... alors que les autres fichiers du
même répertoire sont biens évalués.

Effectivement une solution consiste à trapper l'erreur.

En tous cas bravo pour ta disponibilité.



Hello,

en effet, le problème peut survenir pour diverses raisons, la plus
courante
étant l'accès à un fichier temporairement (ou non) protégé car partagé.

Comme je le disais dans mon post précédent, on peut s'en sortir en
trappant l'erreur dans VB, mais on manque alors l'information concernant
la
vraie cause de l'erreur.

Finalement, une façon élégante de réler le problème consiste
à se définir sa propre fonction de lecture d'attributs et de faire en
sorte
qu'elle remonte proprement l'erreur (pour info) si il y en a une.

Le plus simple et le plus naturel est de faire la fonction en C, de la
mettre dans une Dll et de l'appeler coté VB.

J'ai mis en ligne un petit fichier zip contenant la dll (avec les sources)
et
un programme d'exemple en VB :
http://users.skynet.be/candide/getattr.html

Le code source de la dll est très court :

#include<stdio.h>
#include<stdlib.h>

#include<windows.h>

#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)

#define export __declspec (dllexport)

export long __stdcall GetAttributes(LPCSTR pszString, long *attr, long
*errCode)
{
long loc_attr = 0L;
long ret = 0L;

loc_attr = GetFileAttributes(pszString);

if(loc_attr == INVALID_FILE_ATTRIBUTES)
{
*errCode = GetLastError();
*attr = loc_attr;
ret = 0L;
}
else
{
*errCode = 0;
*attr = loc_attr;
ret = 1L;
}

return ret;
}

La fonction retourne 1 en cas de succès, 0 sinon.
Quand elle retourne 1, l'attribut de fichier est mis dans attr.
Quand elle retourne 0, le code d'erreur est renseigné dans errCode

[note: pour ceux qui veulent en savoir plus sur la création de
dll et l'utilisation en VB, voir la FAQ:
http://faq.vb.free.fr/index.php?question4

L'utilisation en VB est toute simple :

Option Explicit

Private Declare Function GetAttributes _
Lib "clibattr.dll" Alias "" _
(ByVal s As String, attr As Long, errCode As Long)
As Long


Dim s As String
Dim ret As Long
Dim attr As Long
Dim errCode As Long


s = "c:IO.SYS"

ret = GetAttributes(s, attr, errCode)

If ret = 1 Then
' function succeeds
MsgBox "Attributes for file: " & s & " : " & attr & vbCrLf & _
"Text Attr = " & GetAttrStringFromAttr(attr)

Else
' function fails
MsgBox "Error getting attributes for file " & s & vbCrLf & _
"Error code from GetFileAttributes : " & errCode
End If


Et pour obtenir les attributs en clair :

' cf http://msdn.microsoft.com/en-us/library/ee332330(VS.85).aspx

Const FILE_ATTRIBUTE_READONLY As Long = &H1
Const FILE_ATTRIBUTE_HIDDEN As Long = &H2
Const FILE_ATTRIBUTE_SYSTEM As Long = &H4
Const FILE_ATTRIBUTE_DIRECTORY As Long = &H10
Const FILE_ATTRIBUTE_ARCHIVE As Long = &H20
Const FILE_ATTRIBUTE_DEVICE As Long = &H40
Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Const FILE_ATTRIBUTE_TEMPORARY As Long = &H100
Const FILE_ATTRIBUTE_SPARSE_FILE As Long = &H200
Const FILE_ATTRIBUTE_REPARSE_POINT As Long = &H400
Const FILE_ATTRIBUTE_COMPRESSED As Long = &H800
Const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED As Long = &H2000
Const FILE_ATTRIBUTE_OFFLINE As Long = &H1000
Const FILE_ATTRIBUTE_ENCRYPTED As Long = &H4000
Const FILE_ATTRIBUTE_VIRTUAL As Long = &H10000

et la fonction qui va avec :

Private Function GetAttrStringFromAttr(ByVal attr As Long) As String
Dim szAttr As String

If attr And FILE_ATTRIBUTE_READONLY Then
szAttr = szAttr & "READONLY" & "."
End If
If attr And FILE_ATTRIBUTE_HIDDEN Then
szAttr = szAttr & "HIDDEN" & "."
End If
If attr And FILE_ATTRIBUTE_SYSTEM Then
szAttr = szAttr & "SYSTEM" & "."
End If
If attr And FILE_ATTRIBUTE_DIRECTORY Then
szAttr = szAttr & "DIRECTORY" & "."
End If
If attr And FILE_ATTRIBUTE_ARCHIVE Then
szAttr = szAttr & "ARCHIVE" & "."
End If
If attr And FILE_ATTRIBUTE_DEVICE Then
szAttr = szAttr & "DEVICE" & "."
End If
If attr And FILE_ATTRIBUTE_NORMAL Then
szAttr = szAttr & "NORMAL" & "."
End If
If attr And FILE_ATTRIBUTE_TEMPORARY Then
szAttr = szAttr & "TEMPORARY" & "."
End If

If attr And FILE_ATTRIBUTE_SPARSE_FILE Then
szAttr = szAttr & "SPARSE_FILE" & "."
End If
If attr And FILE_ATTRIBUTE_REPARSE_POINT Then
szAttr = szAttr & "REPARSE_POINT" & "."
End If
If attr And FILE_ATTRIBUTE_COMPRESSED Then
szAttr = szAttr & "COMPRESSED" & "."
End If
If attr And FILE_ATTRIBUTE_NOT_CONTENT_INDEXED Then
szAttr = szAttr & "NOT_CONTENT_INDEXED" & "."
End If
If attr And FILE_ATTRIBUTE_OFFLINE Then
szAttr = szAttr & "OFFLINE" & "."
End If
If attr And FILE_ATTRIBUTE_ENCRYPTED Then
szAttr = szAttr & "ENCRYPTED" & "."
End If
If attr And FILE_ATTRIBUTE_VIRTUAL Then
szAttr = szAttr & "VIRTUAL" & "."
End If

GetAttrStringFromAttr = szAttr
End Function

Avec tout ça, on a une nouvelle fonction GetAttribute, qui ne plante
jamais et qui renseigne proprement les erreurs quand il y en a.

A noter : on trouvera la signification des codes d'erreurs retournés
dans errCode ici :
http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

Bonne soirée !


--
Jean-marc Noury (jean_marc_n2)
FAQ VB: http://faq.vb.free.fr/
mailto: remove '_no_spam_' ;