2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: Virtual DOS Drivers (VDD) Support
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9 /* INCLUDES *******************************************************************/
17 #include "registers.h"
19 typedef VOID (WINAPI
*VDD_PROC
)(VOID
);
21 typedef struct _VDD_MODULE
24 VDD_PROC DispatchRoutine
;
25 } VDD_MODULE
, *PVDD_MODULE
;
28 #define BOP_3RDPARTY 0x58 // 3rd-party VDD BOP
30 /* PRIVATE VARIABLES **********************************************************/
32 #define MAX_VDD_MODULES 0xFF + 1
33 VDD_MODULE VDDList
[MAX_VDD_MODULES
] = {{NULL
}}; // TODO: Maybe use a linked list.
34 // But the number of elements must be <= MAXUSHORT
36 /* PRIVATE FUNCTIONS **********************************************************/
38 USHORT
GetNextFreeVDDEntry(VOID
)
40 USHORT Entry
= MAX_VDD_MODULES
;
41 for (Entry
= 0; Entry
< sizeof(VDDList
)/sizeof(VDDList
[0]); ++Entry
)
43 if (VDDList
[Entry
].hDll
== NULL
) break;
48 VOID WINAPI
ThirdPartyVDDBop(LPWORD Stack
)
50 /* Get the Function Number and skip it */
51 BYTE FuncNum
= *(PBYTE
)SEG_OFF_TO_PTR(getCS(), getIP());
62 LPCSTR DllName
= NULL
,
63 InitRoutineName
= NULL
,
64 DispatchRoutineName
= NULL
;
66 VDD_PROC InitRoutine
= NULL
,
67 DispatchRoutine
= NULL
;
69 DPRINT1("RegisterModule() called\n");
71 /* Clear the Carry Flag (no error happened so far) */
74 /* Retrieve the VDD name in DS:SI */
75 DllName
= SEG_OFF_TO_PTR(getDS(), getSI());
77 /* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */
78 if (getES() != 0 || getDI() != 0)
79 InitRoutineName
= SEG_OFF_TO_PTR(getES(), getDI());
81 /* Retrieve the dispatch routine API name in DS:BX */
82 DispatchRoutineName
= SEG_OFF_TO_PTR(getDS(), getBX());
84 DPRINT1("DllName = '%s' - InitRoutineName = '%s' - DispatchRoutineName = '%s'\n",
85 (DllName
? DllName
: "n/a"),
86 (InitRoutineName
? InitRoutineName
: "n/a"),
87 (DispatchRoutineName
? DispatchRoutineName
: "n/a"));
89 /* Load the VDD DLL */
90 hDll
= LoadLibraryA(DllName
);
93 DWORD LastError
= GetLastError();
96 if (LastError
== ERROR_NOT_ENOUGH_MEMORY
)
98 DPRINT1("Not enough memory to load DLL '%s'\n", DllName
);
104 DPRINT1("Failed to load DLL '%s'; last error = %d\n", DllName
, LastError
);
110 /* Load the initialization routine if needed */
113 InitRoutine
= (VDD_PROC
)GetProcAddress(hDll
, InitRoutineName
);
114 if (InitRoutine
== NULL
)
116 DPRINT1("Failed to load the initialization routine '%s'\n", InitRoutineName
);
123 /* Load the dispatch routine */
124 DispatchRoutine
= (VDD_PROC
)GetProcAddress(hDll
, DispatchRoutineName
);
125 if (DispatchRoutine
== NULL
)
127 DPRINT1("Failed to load the dispatch routine '%s'\n", DispatchRoutineName
);
133 /* If we arrived there, that means everything is OK */
135 /* Register the VDD DLL */
136 Entry
= GetNextFreeVDDEntry();
137 if (Entry
== MAX_VDD_MODULES
)
139 DPRINT1("Failed to create a new VDD module entry\n");
144 VDDList
[Entry
].hDll
= hDll
;
145 VDDList
[Entry
].DispatchRoutine
= DispatchRoutine
;
147 /* Call the initialization routine if needed */
148 if (InitRoutine
) InitRoutine();
157 /* Unload the VDD DLL */
158 if (hDll
) FreeLibrary(hDll
);
160 /* Set the Carry Flag to indicate that an error happened */
165 // /* Clear the Carry Flag (success) */
172 /* UnRegisterModule */
175 WORD Entry
= getAX();
177 DPRINT1("UnRegisterModule() called\n");
180 if (Entry
> MAX_VDD_MODULES
|| VDDList
[Entry
].hDll
== NULL
)
182 DPRINT1("Invalid VDD DLL Handle: %d\n", Entry
);
188 /* Unregister the VDD DLL */
189 FreeLibrary(VDDList
[Entry
].hDll
);
190 VDDList
[Entry
].hDll
= NULL
;
191 VDDList
[Entry
].DispatchRoutine
= NULL
;
198 WORD Entry
= getAX();
200 DPRINT1("DispatchCall() called\n");
203 if (Entry
> MAX_VDD_MODULES
||
204 VDDList
[Entry
].hDll
== NULL
||
205 VDDList
[Entry
].DispatchRoutine
== NULL
)
207 DPRINT1("Invalid VDD DLL Handle: %d\n", Entry
);
213 /* Call the dispatch routine */
214 VDDList
[Entry
].DispatchRoutine();
220 DPRINT1("Unknown 3rd-party VDD BOP Function: 0x%02X\n", FuncNum
);
227 /* PUBLIC FUNCTIONS ***********************************************************/
229 VOID
VDDSupInitialize(VOID
)
231 /* Register the 3rd-party VDD BOP Handler */
232 RegisterBop(BOP_3RDPARTY
, ThirdPartyVDDBop
);