[WIN32K] Tag more pool allocations
[reactos.git] / reactos / subsystems / win32 / win32k / ldr / loader.c
index a63eb95..bc867c2 100644 (file)
  *  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,
@@ -80,7 +84,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
         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);
@@ -89,7 +93,7 @@ LdrGetProcedureAddress (IN PVOID BaseAddress,
    return STATUS_PROCEDURE_NOT_FOUND;
 }
 
-PVOID STDCALL
+PVOID APIENTRY
 EngFindImageProcAddress(IN HANDLE Module,
                        IN LPSTR ProcName)
 {
@@ -170,7 +174,7 @@ EngFindImageProcAddress(IN HANDLE Module,
       return NULL;
     }
   RtlInitAnsiString(&ProcNameString, ProcName);
-  Status = LdrGetProcedureAddress(Module,
+  Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress,
                                  &ProcNameString,
                                  0,
                                  &Function);
@@ -186,37 +190,75 @@ EngFindImageProcAddress(IN HANDLE Module,
  * @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 */