* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* $Id$
*
*/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
+
+extern LIST_ENTRY GlobalDriverListHead;
+
+
/*
* Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from
* here, though.
*/
-NTSTATUS STDCALL
+NTSTATUS APIENTRY
LdrGetProcedureAddress (IN PVOID BaseAddress,
IN PANSI_STRING Name,
IN ULONG Ordinal,
Ordinal &= 0x0000FFFF;
if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
{
- *ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[Ordinal - ExportDir->Base]);
+ *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG_PTR)AddressPtr[Ordinal - ExportDir->Base]);
return STATUS_SUCCESS;
}
DPRINT1("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
return STATUS_PROCEDURE_NOT_FOUND;
}
-PVOID STDCALL
+PVOID APIENTRY
EngFindImageProcAddress(IN HANDLE Module,
IN LPSTR ProcName)
{
return NULL;
}
RtlInitAnsiString(&ProcNameString, ProcName);
- Status = LdrGetProcedureAddress(Module,
+ Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress,
&ProcNameString,
0,
&Function);
* @implemented
*/
HANDLE
-STDCALL
+APIENTRY
EngLoadImage (LPWSTR DriverName)
{
- SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
- NTSTATUS Status;
+ SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
+ PDRIVERS DriverInfo = NULL;
+ NTSTATUS Status;
- RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
- Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
- if (!NT_SUCCESS(Status)) return NULL;
+ RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
+ if( !IsListEmpty(&GlobalDriverListHead) )
+ {
+ PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink;
+ PDRIVERS Current;
+ /* probably the driver was already loaded, let's try to find it out */
+ while( CurrentEntry != &GlobalDriverListHead )
+ {
+ Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry);
+ if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) {
+ DriverInfo = Current;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ };
+ }
- return (HANDLE)GdiDriverInfo.ImageAddress;
-}
+ if( !DriverInfo )
+ {
+ /* the driver was not loaded before, so let's do that */
+ Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+ if (!NT_SUCCESS(Status)) {
+ DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status);
+ }
+ else {
+ DriverInfo = ExAllocatePoolWithTag(PagedPool, sizeof(DRIVERS), TAG_DRIVER);
+ DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength;
+ DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length;
+ DriverInfo->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool, GdiDriverInfo.DriverName.MaximumLength, TAG_DRIVER);
+ RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName);
+ DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer;
+ DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress;
+ InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry);
+ }
+ }
+ return DriverInfo;
+}
-/*
- * @unimplemented
- */
-HANDLE
-STDCALL
-EngLoadModule(LPWSTR ModuleName)
+VOID
+APIENTRY
+EngUnloadImage ( IN HANDLE hModule )
{
- SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
NTSTATUS Status;
+ PDRIVERS DriverInfo = (PDRIVERS)hModule;
- // FIXME: should load as readonly
+ DPRINT("hModule 0x%x\n", hModule);
- RtlInitUnicodeString (&GdiDriverInfo.DriverName, ModuleName);
- Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
- if (!NT_SUCCESS(Status)) return NULL;
+ Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
+ DriverInfo->SectionPointer, sizeof(PVOID));
- return (HANDLE)GdiDriverInfo.ImageAddress;
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwSetSystemInformation failed with status 0x%08X\n",
+ Status);
+ }
+ else
+ {
+ ExFreePool(DriverInfo->DriverName.Buffer);
+ RemoveEntryList(&DriverInfo->ListEntry);
+ ExFreePool(DriverInfo);
+ }
}
/* EOF */