Appel d'une DLL Win32 à partir d'une appli DOS 16bit

telghali
Appel d'une DLL Win32 à partir d'une appli DOS 16bit

Bonjour,
Je suis en train d’essayer de faire communiquer une application DOS 16 bit (ce n’est pas une Win16) écrite en assembleur (TASM) avec une DLL Win32. L’application DOS devra appeler des fonctions exportées par la DLL via le mécanisme « generic thunk ». Pouvez vous m’informer si cette solution est faisable. Et si oui, quelles sont les grandes lignes de la solution.
Merci de votre aide.

fredericmazue

Bonjour,

Quote:
Je suis en train d’essayer de faire communiquer une application DOS 16 bit (ce n’est pas une Win16) écrite en assembleur (TASM) avec une DLL Win32

Houlà...
Je dis houlà parce que ce n'est pas une mince affaire...

Quote:
Pouvez vous m’informer si cette solution est faisable

C'est dans l'absolu faisable. Quant à savoir s'il faut le faire, c'est une autre question qui mérite d'être posée.

Les grandes lignes:

- Sauf erreur (ou oubli) de ma part avec une appli *strictement* DOS, tu ne peux pas. Les dll n''existaient pas sous DOS. Donc tu dois trouver un vieux compilateur 16 bits Microsoft/Windows et recompiler ton code DOS en une appli "console" 16 bits incluant le code assembleur.

- Ensuite tu dois écrire une dll 16 bits dont ton appli invoquera des fonctions (donc de toutes façons tu dois dénicher un vieux compilo 16 bits)

- le rôle de la dll 16 bits est d'établir le pont entre 16 et 32 bits avec les fameux chunks en effet.

- Enfin (toujours sauf erreur ou oubli de ma part) ceci ne marchera de toutes façons que sur Windows 9x jusqu'à Millenium inclus. Pas après.

Bon courage avec les thunks, c'est difficile. Mais Microsoft le document encore
Exemple: http://support.microsoft.com/kb/154093/fr

Bon la question est que fait ton appli DOS ? Je suppose que tu veux accéder directement à quelque chose en chuntant le mode protégé. La méthode à préconiser est d'écrire un driver. Les thunks 16/32 c'est vraiment d'un autre âge....

Bon courage....

telghali

Merci pour la réponse,
Mon vieux programme Dos 16 bit est un gros logiciel qui marche très bien. Sauf qu’il communique avec des cartes (ISA) obsolètes, qui seront remplacés par des nouvelles cartes PCI. Ces nouvelles cartes ne parlent que Win32 (DLL fournie par le fabriquant).

Donc l’objectif est de garder le logiciel DOS 16bit (- la partie de communication) qui tournera sous VDM (Virtual Dos Machine) et appeler la nouvelle DLL via « generic thunks ».
Dans l’absolue la logique est correcte, dans la pratique c’est une autre chose.
Remarque: « generic thunks » est un mécanisme que existe sous XP, NT à distinguer % à flat thunks.

fredericmazue

Quote:
Remarque: « generic thunks » est un mécanisme que existe sous XP, NT à distinguer % à flat thunks.

Ah oui c'est vrai, j'avais complètement oublié ! :)

Quote:
Donc l’objectif est de garder le logiciel DOS 16bit (- la partie de communication) qui tournera sous VDM (Virtual Dos Machine) et appeler la nouvelle DLL via « generic thunks ».

Il y a quelque chose que je ne suis pas bien. Par quelle magie ton programme DOS "tel qu'il est" va-t-il appeler une dll 16 bits ?

Quote:

Dans l’absolue la logique est correcte, dans la pratique c’est une autre chose.

Heu oui comme tu dis

Quote:
nouvelles cartes PCI. Ces nouvelles cartes ne parlent
que Win32 (DLL fournie par le fabriquant).

Oui ça s'appelle un pilote (driver comme je disais dans lepost d'avant) Alors si je comprends bien tu penses invoquer des fonction de drivers directement à travers un thunks ?
Bon courage
Dailleurs je me demande même si ça peut marcher. Appeler du code 32 bits depuis du 16 c'est une chose mais appeler une dll de driver qui tourne en mode noyau c'est encore une autre chose je pense.

Enfin peut être que je ne comprends pas bien ce que tu veux faire. :)

telghali

La DLL que je compte appelée ne tourne pas en mode noyau. C’est une API fournie par un constructeur pour manipuler la carte.
Cordialement,

fredericmazue

Quote:
La DLL que je compte appelée ne tourne pas en mode noyau. C’est une API fournie par un constructeur pour manipuler la carte.

Ah ok, une dll de programmation en plus du pilote.
Je n'avais pas compris comme ça.

Oui maintenant je pense que je vois à peu près clairement (grosse fatigue ce soir :) ) ce que tu veux faire.
Mais j'ose quand même une question ;) Ce programme DOS tu as les sources ?

telghali

Oui, codé en assembleur sous avec Tasm

fredericmazue

Tu devrais pouvoir arriver à tes fins. Le tout est de trouver un vieux compilateur C 16 bits pour écrire la dll. Dans une vieille DDK par exemple.

fredericmazue

Ce matin en prenant mon thé, j'ai pensé à toi. Ta question est à la fois pas banale et intéressante. Si je reprends la discussion d'hier, ce n'est pas pour accéder directement à des chips que tu veux garder l'appli DOS. C'était ce que j'avais compris au départ, mais manifestement non, sinon tu ne parlerais pas d'appeler une dll 32 "de programmation" de la carte. Alors je me suis dit, mais pourquoi diable veut-il garder son appli DOS plutôt que la porter vers une appli console 32 en C ou en C++ ?

Tu dois avoir tes raisons pour. Moi je ne vois que des raisons contre. Dis moi si je me trompe.
D'abord, sauf aveuglement de ma part, ton appli DOS tu ne pourras pas la garder, car tu ne pourras pas la modifier simplement pour appeler les dll 16 bits. Les applis DOS ne connaissent pas les dll. Donc tu vas devoir porter l'appli en une WIN16 à look DOS. Mode réel ou mode protégé, c'est la question. (D'ailleurs tu n'as pas précisé si ton appli DOS était en mode réel ou en mode protégé DPMI, mais sur le fond ça ne change pas grand chose). En mode réel, mon ampéropifomètre me dit que le mécanisme des thunks ne va pas marcher (mais c'est à vérifier). En mode protégé ok. Mais cela va très probablement impliquer de grosses répercussion sur l'appli de départ. Et après (ou parallèlement parce que faut pouvoir tester aussi ;) ), tu dois écrire les dll 16 de thunk. Bref je trouve que ça fait beaucoup de boulot, de difficultés techniques, de risque d'erreurs et de perte de temps.
A ta place moi je porterais l'appli DOS en Win32 direct

Non ? Qu'a-t-elle de si extraordinaire cette appli DOS ?

telghali

Bonjour,
Au départ, J'ai estimé que le coût de porter tt l'application en Win32 (ça revient à la réécrire en c ou c++ par exemple) est beaucoup plus grand qu'écrire un bout de code qui remplacera le module de communication actuel avec les ancienne cartes. Le nouveau module de comm accède à l'API de la nouvelle carte via "generic thunks".
Porter tt l'appli. change complètement la nature/l'étendu du boulot à faire.
Mais je me demande maintenant si j'ai encore raison.
Question: comment savoir si je sui en mode protégé DMPI ou réel?

fredericmazue

Quote:
beaucoup plus grand qu'écrire un bout de code

Toute la question est là. Je crains que le "bout de code" ne soit un peu gros, et aussi que les difficultés à écrire les thunks coûtent cher en terme de temps. Je l'ai fait une fois (en flat thunk pas en generics) et je n'en garde pas un bon souvenir :(

Quote:
Porter tt l'appli. change complètement la nature/l'étendu du boulot à faire.

La nature oui :)
L'étendue, hum faut voir.
Quote:
Mais je me demande maintenant si j'ai encore raison.

C'est le genre de décision qu'il faut réfléchir longuement avant de se lancer.
Mais de toutes façons il y a quelque chose qui pèse très lourd dans la balance: tu ne peux pas reprendre ton code DOS tel que. Tu dois le porter vers Win 16 pour pouvoir appeler une dll. et ce ne sera pas de la tarte car probablement ton code est en mode réel. Tu devras le ré-écrire en mode protégé pour que ça marche avec les thunks (à vérifier toutefois) et déjà ça, rien que pour retrouver les vieilles documentation, c'est déjà tout un boulot :( Quitte à porter vers Win, moi je choisirais directement le 32 :)

Quote:
Question: comment savoir si je sui en mode protégé DMPI ou réel

Si tu n'en sais rien, tu es probablement en mode réel. Si oui, tu ne verras pas au début du code d'instructions "bizarres" qui basculent le processeur en mode protégé (me rappelle plus lesquelles, c'est vieux :oops: ) et tu verras plein d'appels classiques à BIOS et DOS sous forme de int13 int 21. Si c'est le cas, ça, ça ne marchera pas je pense avec les thunks et tu devras ré-écrire en mode protégé. Mais... voir plus loin

Donc si tu n'es pas en mode réel tu vas le voir puisque tu n'aurais pas de int 21 mais d'autre compliqués qui émulent les premiers

Mais disais je, dans tous les cas, pour faire ce que tu veux faire, il faut être capable d'appeler une dll windows 16 bits. En DOS mode réel on ne peut pas, c'est sûr, donc tu dois tout changer, et en mode DPMI, je ne pense pas que l'on puisse non plus, donc tu dois tout changer, c'est à dire porter ton code assembleur en Win16 ce qui est une grosse galère. Et tu vas alors te heurter immanquablement à DMPI dans l'autre sens, c'est à dire pour émuler les anciens appels DOS depuis ton code Win 16

Heu je ne sais pas si je suis très clair.
:oops:

Et après tout ça, faut écrire les thunks. Alors je te résume ma pensée: Pas un "bout de code" mais une grosse galère. AMHA.
Je préfère que ça soit toi qui le fasse que moi :)

telghali

Je pense que c'est en mode réel
car, il est compilé avec TASM et linké avec tlink (option /Tde)

fredericmazue

Quote:
Je pense que c'est en mode réel
car, il est compilé avec TASM

Faut pas s'y fier. TASM (Borland si je me rappelle bien n'est-ce pas ?) peut aussi générer du mode protégé. Je l'ai fait à une époque

Quote:
linké avec tlink (option /Tde)

Heu je me rappelle pas :oops:
Ca fait longtemps que je n'ai pas touché à ces vieux clous.

Regarde dans ton code comme je t'ai dit. Ca va te sauter au yeux je pense.

telghali

mon programme utilise les instructions assembleur in, out pour accèder directement à un hardware: donc c'est du mode réel

fredericmazue

En effet

Hem... des in et des out...
Donc ton programme DOS écrivait bien directement dans des ports.
Pour réussir à garder ton appli DOS tu n'es pas au bout de tes peines, je le crains.
Plus on parle de ton problème et plus il me semble que c'est une mauvaise voie.

telghali

Je pense que cette tâche est du type: "reanimate the dead" or "reach the moon"
:P

telghali

c'est une mission du genre "reanimate the dead" ou "reach the moon" en 2 jours

fredericmazue

Raison de plus pour choisir la voir la plus rapide qui n'est pas celle des thunks AMHA

Et puis il faut penser à l'avenir aussi. Les thunks ne seront pas supportés encore très longtemps je suppose.

Au fait le sont ils dans Vista ? Je n'en sais rien. C'est une question à poser sur notre forum dédia à Vista :)

telghali

Bonjour,
J'ai trouvez une solution pour appeler du code Win16 à partir d'une DLL32 bits. Elle se base sur le résultat du travail d'Eric Sigoillot. Tout repose sur l'introduction dans le code de deux octets : C4C4h.

Voici les explications d'Eric :
"A priori, sous Dos, impossible d'appeler une fonction de NTVDM, qui est une application 32 bits. C'est là qu'intervient la fameuse combinaison C4C4h. En effet, cet opcode est totalement incompatible avec le processeur. Résultat ? Plantage normalement ! Mais c'est sans compter sur le fait que le Dos n'est qu'émulé sous NT. Ainsi, NTVDM va récupérer l'erreur et l'analyser. NTVDM est ainsi conçu pour entreprendre une action particulière si l'erreur est déclenchée par C4C4h. Si c'est le cas, il lit l'octet ou les deux octets qui suivent notre opcode magique pour se décider. S'il est inconnu, plantage assuré ! Mais sinon, c'est tout bon...
Ainsi, je connais 4 numéros de fonctions qui servent à : charger une VDD (une DLL 32 bits particulière), le décharger, appeler une fonction d'un VDD, et rendre la main au VDD après un appel particulier. Victoire ! "
Qu'en dite vous?
Cordialement,

fredericmazue

Quote:
Qu'en dite vous?

Très franchement ? :twisted:

D'abord:

Quote:
cet opcode est totalement incompatible avec le processeur

Quel processeur :?: :?:
Quote:
Ainsi, NTVDM va récupérer l'erreur et l'analyser.

Sans blague ?
Et bien sûr tout cela est garanti par Microsoft, documenté, certifié, et tout et tout ?

Bon ce que j'en dis ...
J'en dis que ce n'est pas une façon de programmer. Que ça marchera jusqu'au jour où ça ne marchera pas.
J'en dis aussi que si j'avais un collaborateur qui développe comme ça, je le virerais illico pour faute professionnelle grave. Sans blague.

A part ça il y a quelque chose que je ne suis plus

Quote:
J'ai trouvez une solution pour appeler du code Win16 à partir d'une DLL32 bits

Au départ tu voulais faire l'inverse. De 16 vers 32 D'ailleurs le procédé que tu décris fait l'inverse n'est-ce pas ?
telghali

Faute de frappe, c'est pour appeler du Win32 bits (DLL) à partir d'un code dos 16 bits.

Vous avez raison! Cette pseudo solution qui se base sur des mécanismes obscurs n'est pas utilisable dans un environnement professionnel:
- ce n'est pas documenté, ni certifié par Microsoft.
- risque de ne plus marché après une simple mise à jour de l'OS ou de NTVDM
- complexe à mettre en place et surtout maintenir

fredericmazue

Quote:
- risque de ne plus marché après une simple mise à jour de l'OS ou de NTVDM

D'autant plus que quand on y réfléchit, le comportement sous NT que décrit Eric Sigollot, ça n'est ni plus ni moins qu'énorme trou béant de sécurité.
Bon ça ne fait jamais qu'un de plus ;) :lol:
Mais ça sera patché tôt ou tard, à supposer même que ça existe sous XP et Vista

telghali

Bonjour,
Cette "solution" m'a mis sur le chemin de l'issue de secoure :)
En effet, j'ai consulté la documentation de DDK (driver developpemet kit) (version Win 2000 pour l'instant) au sujet des VxD (Virtual Device Drivers) et j'ai trouvé ça: (je m'excuse pour le volume !)

Intro:
"A VDD need only be written to support special-purpose hardware devices that operate under an MS-DOS application. The provided VDM has built-in support for commonly used hardware such as serial communication ports, video, mouse"

aussi: (c'est mon application)
"there are some MS-DOS applications that depend on custom hardware, such as a fax board or a 3270 communications board. Generally, these applications have a plug-in hardware board they manipulate directly through 80386/80486 I/O port IN and OUT instructions and by writing directly to memory on the board. These applications might also use DMA to transfer data to and from the board. In an MS-DOS environment, these operations allow the application or its 16-bit driver to get direct access to the hardware device"

La solution:
"To support an MS-DOS application using special hardware in the Windows NT/Windows 2000 environment, the application developer must write a 32-bit kernel-mode device driver to access the board hardware. The developer must also write a VDD to translate operations performed by the MS-DOS application into the corresponding kernel-mode device driver calls for the particular board. The paired kernel-mode device driver and VDD for the device enable the original MS-DOS application to run in the VDM layer"

fredericmazue

Quote:
La solution:
the application developer must write a 32-bit kernel-mode device driver to access the board hardware

LOL :!: :lol:

Vraiment très amusant. Qu'est-ce donc que j'avais écrit dans mon tout premier post sans réussir à me faire entendre ? Je me cite ;)

Quote:
Bon la question est que fait ton appli DOS ? Je suppose que tu veux accéder directement à quelque chose en shuntant le mode protégé. La méthode à préconiser est d'écrire un driver.

Bon c'est vrai que je ne suis pas entré dans le détail du vxd. Mais bon... ;) :lol:

telghali

J'avoue :oops: je suis totalement nouveau dans le domaine (Asm, drivers, etc) et :
1- je dois trouver une solution en très peu de temps
2- tester tt les problèmes de faisabilités
3-la solution doit être la moins coûteux possible
etc., etc.
Il m'arrive de rater des choses.
mais votre aide a été inestimable :D

fredericmazue

Quote:
J'avoue je suis totalement nouveau dans le domaine (Asm, drivers, etc) et :

Vous n'avez rien à avouer. Même sans y être nouveau le sujet est difficile.
Et puis la discussion a été interessante et de bon niveau. Ca a été un plaisir :)

Quote:
mais votre aide a été inestimable

Très gentil à vous, merci :)

Alors je me sens encouragé à continer :)
En ce qui concerne les points 1, 2 et 3 de votre message précédent, voilà mon avis. Coder des drivers Windows , ça se fait, mais il y a un apprentissage et des pièges. Je reste convaincu que porter l'appli DOS en une appli Win32 est la solution la plus rapide, la moins coûteuse et la plus fiable.
Bon courage pour votre travail, quel que soit votre choix :)