xela138
Messages postés10Date d'inscriptionmardi 26 octobre 2004StatutMembreDernière intervention22 avril 2010
-
20 avril 2009 à 14:03
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 2014
-
24 avril 2009 à 09:31
Bonjour à tous et merci à ceux qui pouront m'éclairer sur mon problème.
Mon client est un projet universitaire(il est sensé faire une mise à jour automatique et silencieuse d'ou la DLL)...sont role est d'interpréter un ordre sur une page web et de l'executer. Le projet tourne en version EXE sans AUCUN problèmes, j'ai récemment eu l'envie de le mettre sous forme de DLL mais je n'ai aucun bessoin de faire appel à ses fonctions par un programme extérieur donc je n'ai pas mis de .def je n'ai pas d'éclaré mes fonctions avec un extern "C" __cdecl void mafunc(){...}, je fais juste un apel à ma fonction d'initialisation au moment du chargement de la DLL avec:
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
init(); // ma fonction....
break;
................
................
Tous se passe correctement, les MessageBox() sont affichés, je peut utiliser le registre, les socket marches.....
Maintenant le problème :)
--------> Au moment d'utiliser la fonction de l'API win32 DownloadToFile, la DLL se fige et ne fait plus rien.....Gros problème quand meme....
J'ai essayé avec les symbolles, sans les symbolles, j'ai essayé avec URLDownloadToFile(), on dirait que la DLL ne peut pas se servir de HRESULT ou HINSTANCE, je compile en "use MFC instatic lib", je n'ai jamais eu ce genre de problemes avant....Sa fait deja plus de 72h que je cherche le probleme, mais personne n'est capable de me répondre, le projet compile sans erreur juste quelques warnings....
Et tous se fige pile au moment ou j'appel xURLDownloadToFile()
Le problème vient à priori des HRESULT et HINSTANCE, mais je ne voit pas comment les déclarer différements.
Je suis perdu help me !!!!
J'espere que brunews pourra apporter sa contribution héhé car je pense qu'il est l'homme de la situation(MVP).
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 20 avril 2009 à 21:58
Inutile d'aller chercher ailleurs, la raison précise a bien été indiquée par rt15:
Pas de loadLibrary ni FreeLibrary depuis DLL_PROCESS_ATTACH sinon réentrance de code donc boucle sans fin.
Il faut exporter ta fonction ou te lier en static à urlmon, exporter serait le mieux.
J'insiste malgré tout sur le fait que DLL_PROCESS_ATTACH n'est pas du tout le moment de longs traitements tels que téléchargement de fichiers car ça devrait se faire dans un thread.
Azer33:
Il est clair qu'un MVP n'a pas science infuse sur tous produits MS.
Mon cas:
- Je n'utilise quasi rien de VC++ hors l'éditeur et bouton compiler.
- Je me sers de très peu de fonctions Win32 (je ne fais pas d'interfaces graphiques dans mon taf).
- Je ne fais jamais de C++ (C et ASM only).
C'est connu depuis des années de la direction du prog MVP et je suis pourtant MVP VC++, simplement parce que c'est la categ la plus voisine de ce que je fais.
Par contre comme newbie t'ira chercher ailleurs, suis dispo pour te filer cahier des charges d'un calculateur statistique et on comparera les perfs.
Tu es dans quelle catégorie avec quel ID MVP ???
Je te signale aussi que les NON réponses sur le forum ont fini par me burner, telles celles de jeffy131 (surement un autre de tes pseudos). Les comptes CS ne faisant que cela sont dorénavant supprimés. Soit on vient aider, soit on passe son chemin.
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 21 avril 2009 à 11:15
Azer33 -> Ah ok. En fait, quand je poste sur usenet, je suis pro. Mais quand je poste sur cppfrance je le suis pas. Logique.
xela138 -> Effectivement, charger (Dans le .exe) toutes les dlls nécessaires à URLDownloadToFile avant d'appeler le point d'entrée de la dll ne corrige pas. Effectivement, le problème est ailleurs. Breum, pas facile de faire bosser un débogueur sur le sujet... Mais un petit coup de process monitor donne un résultat très intéressant :
Dernier appel : CreateThread. Un petit coup de google pour avoir la
confirmation... CreateThread dans un dllmain, ça peut générer des
DeadLock. Ca semble être le cas ici.
xela138
Messages postés10Date d'inscriptionmardi 26 octobre 2004StatutMembreDernière intervention22 avril 2010 20 avril 2009 à 14:31
Tous d'abord merci pour ta rapidité^^.
Mais alors comment faire pour utiliser cette API dans la DLL sans programme externe...Si MessageBox() passe, le reste devrait passer sans problème vu que c'est un PE. Et qu'est ce qui limite DLL_PROCESS_ATTACH.
Désolé sa fait que deux jours que j'utilise les DLL....et meme dans les nombreux tutos que j'ai lu ce n'ai pas définit clairement vus que la DLL ne sert pas à sa.
Vous n’avez pas trouvé la réponse que vous recherchez ?
xela138
Messages postés10Date d'inscriptionmardi 26 octobre 2004StatutMembreDernière intervention22 avril 2010 20 avril 2009 à 14:42
En gros la question c'est : Doit-je réecrire DownloadToFile moi meme pour que sa marche?... Aparement toutes les manipulations standard marchent meme à travers de nombreuses fonctions et sans problèmes.
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 20 avril 2009 à 19:19
Salut,
[quote=msdn]
The entry-point function should perform only simple initialization or termination tasks. It must not call the LoadLibrary or LoadLibraryEx function (or a function that calls these functions), because this may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code.
/quote
Te lier statiquement à urlmon peut régler le problème, via un .lib (Tu peux te faire ton .lib)... Mais bon exporter une bête fonction serait certainement beaucoup plus propre et moins risqué.
xela138
Messages postés10Date d'inscriptionmardi 26 octobre 2004StatutMembreDernière intervention22 avril 2010 20 avril 2009 à 19:37
Oui j'ai remarqué que chargé une DLL depuis une autre DLL été pas trés malin, du coup j'ai fait un loader qui charge les DLLs nécéssaires au préalable. Cependant le probleme reste entier, j'ai fait apel à un viel ami à moi qui a une grande expérience en la matière, il a débugué le soft et n'a trouvé aucune erreurs, il a qualifié sa de "strange",....!@##!? l'API windows ne renvoi rien sur HRESULT. Je suis actuellement en train de coder une fonction de substitution pour DownloadToFileA. Si quelqu'un sait comment faire pour utiliser sa dans une DLL je suis preneur!!!
PS: je n'exporte pas de fonction donc il me semble difficile de lié mon .lib à urlmon.dll
je pense pouvoir faire que sa #pragma comment(lib,"Urlmon.lib").
Et encore merci pour la rapidité et la qualité des réponses :)
Azer33
Messages postés6Date d'inscriptiondimanche 4 janvier 2009StatutMembreDernière intervention25 mai 2009 20 avril 2009 à 19:50
Tu peux essayer de demander chez les réseaux pros (les vrais), BBS et Usenet (Win32, winapi)
(rappel : le programme MVP n'a rien à voir avec un quelconque professionnalisme,
puisque le but est de réduire le budget support technique en ramassant un maximum de newbies :
aucun des 7 experts Win32 français n'est MVP par exemple...)
(étant MVP moi-même, j'ai vite compris...)
xela138
Messages postés10Date d'inscriptionmardi 26 octobre 2004StatutMembreDernière intervention22 avril 2010 20 avril 2009 à 20:08
Ok merci je vais aller faire un tour de ce coté, et continuer mon downloader, car je pense qu'il n'y as pas de sollution as ce problème. Si quelqu'un est intéressé je peut lui envoyer le project^^ mais faudrait t'il encore savoir quelles sont les limitations de la DLL. (On ne fait pas de longs traitements dans DLL_PROCESS_ATTACH, c'est
juste l'endroit de qlqs initialisations rapides mais pas plus.)
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 20 avril 2009 à 22:13
et aussi Azer33:
je prends le temps de faire des tests pour voir ce qui se passe:
http://brunews.com/tstDownl.zip Si on recompile la DLL en décommentant la ligne:
call Download
on peut monitorer la récursion du code.
Répéter toujours 'aller voir newsgroup trucbidule et autre usenet' n'apporte rien, c'est de la pollution.
xela138
Messages postés10Date d'inscriptionmardi 26 octobre 2004StatutMembreDernière intervention22 avril 2010 23 avril 2009 à 18:30
Voila j'ai fini par trouver un remède à mon problème en téléchargeant moi meme le fichié je poste donc le code qui m'as permis de remplacer DownloadToFileA. Cela dit cette methode n'est pas du tous approprié comme l'on démontré brunews et rt15, le seul intéret est d'avoir une DLL qui peut fonctionner sans EXE, regsvr32.exe suffit pour charger la DLL...
int downloadurl (VOID)
{
SOCKET sockfd;
WSADATA wsaData;
struct hostent *host;
struct sockaddr_in dest_addr;
if (WSAStartup(0x202,&wsaData) == SOCKET_ERROR) {
WSACleanup();
return -1;
}
if ( (host=gethostbyname("127.0.0.1")) == NULL) { /* Put your server here */
perror("gethostbyname");
return 1;
}
memset(&dest_addr,0,sizeof(dest_addr));
memcpy(&(dest_addr.sin_addr),host->h_addr,host->h_length);
/* Prepare dest_addr */
dest_addr.sin_family= host->h_addrtype;
dest_addr.sin_port= htons(80); /* PORT */
if ((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0) {
perror("socket");
return 1;
}
/* Connect*/
if (connect(sockfd, (struct sockaddr *)&dest_addr,sizeof(dest_addr)) == -1){
perror("connect");
return 1;
}
char req[1024]="0";
const char requete[]=
"GET /hello_prog.exe HTTP/1.0\r\n"
"User-Agent: Mozilla/5.0 (Windows NT 6.0; fr; rv:1.9.0.4) Firevox/3.0.4\r\n"
"\r\n";
printf(requete);
send(sockfd,requete,sizeof(requete),0); /* send GET header */
/* Receive until the peer closes the connection */
FILE *zfile;
zfile=fopen("temp.exe","ab+");
int iResult;
char recvbuf[DEFAULT_BUFLEN]="\0";
char exebuf[DEFAULT_BUFLEN]="\0";
int recvbuflen = DEFAULT_BUFLEN;
int x=0;
int y=0;
int i=0;
int b=0;
do
{
iResult = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
if ( iResult > 0 )
{
if(b==0)/* parse the first packet! */
{
b=1;
/* This is totally bullshit you know that */
while(!(recvbuf[x] == 'M' && recvbuf[x+1] == 'Z')) // Some bug with "!="
{
x++;
}
for(i=x;i<=512;i++)
{
exebuf[y]=recvbuf[i];
y++;
}
b=1;
fwrite (exebuf, sizeof(char), y-1, zfile);
printf("Bytes received: %d\n", iResult);
}
else
fwrite (recvbuf, sizeof(char), iResult, zfile);
}
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while( iResult > 0 );
fclose(zfile);
#ifdef WIN32
closesocket(sockfd);
WSACleanup();
#else
close(sockfd);
#endif
}
Et encore merci à tous ceux qui m'ont apportés leur aide. :)
cs_rt15
Messages postés3874Date d'inscriptionmardi 8 mars 2005StatutModérateurDernière intervention 7 novembre 201413 24 avril 2009 à 09:31
C'était donc ça !
Ca me fait penser à rundll32, qui permet d'exécuter une fonction exportée d'une dll, à condition que son prototype suive une convention qui va bien.