Author: ion
Date: Wed Jan 20 17:00:18 2016
New Revision: 70629

URL: http://svn.reactos.org/svn/reactos?rev=70629&view=rev
Log:
[BOOTLIB]: Begin PE loader. Works so far. Next up is loading the sections, 
zeroing out the .bss, and computing checksum.

Modified:
    trunk/reactos/boot/environ/include/bl.h
    trunk/reactos/boot/environ/lib/misc/image.c

Modified: trunk/reactos/boot/environ/include/bl.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?rev=70629&r1=70628&r2=70629&view=diff
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h     [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h     [iso-8859-1] Wed Jan 20 
17:00:18 2016
@@ -147,6 +147,13 @@
 #define BL_LOAD_IMG_UNKNOWN_BUFFER_FLAG                 0x08
 #define BL_LOAD_IMG_COMPUTE_SIGNATURE                   0x10
 #define BL_LOAD_IMG_COMPUTE_HASH                        0x40000
+
+#define BL_LOAD_PE_IMG_VIRTUAL_BUFFER                   
BL_LOAD_IMG_VIRTUAL_BUFFER
+#define BL_LOAD_PE_IMG_CHECK_MACHINE                    0x02
+#define BL_LOAD_PE_IMG_EXISTING_BUFFER                  
BL_LOAD_IMG_EXISTING_BUFFER 
+#define BL_LOAD_PE_IMG_COMPUTE_HASH                     0x10
+#define BL_LOAD_PE_IMG_CHECK_SUBSYSTEM                  0x80
+#define BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY           0x200
 
 /* ENUMERATIONS **************************************************************/
 

Modified: trunk/reactos/boot/environ/lib/misc/image.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/misc/image.c?rev=70629&r1=70628&r2=70629&view=diff
==============================================================================
--- trunk/reactos/boot/environ/lib/misc/image.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/misc/image.c [iso-8859-1] Wed Jan 20 
17:00:18 2016
@@ -655,15 +655,240 @@
 ImgpLoadPEImage (
     _In_ PBL_IMG_FILE ImageFile,
     _In_ BL_MEMORY_TYPE MemoryType,
-    _Out_ PVOID* ImageBase,
+    _Inout_ PVOID* ImageBase,
     _Out_ PULONG ImageSize,
-    _Out_ PVOID Hash,
+    _Inout_opt_ PVOID Hash,
     _In_ ULONG Flags
     )
 {
-    /* Micro-PE loader (no imports/exports/etc) */
-    EfiPrintf(L"PE not implemented\r\n");
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    ULONG FileSize, HeaderSize;
+    PVOID ImageBuffer;
+    BL_IMG_FILE LocalFileBuffer;
+    PBL_IMG_FILE LocalFile;
+    PVOID VirtualAddress;
+    ULONGLONG VirtualSize;
+    PHYSICAL_ADDRESS PhysicalAddress;
+    PIMAGE_NT_HEADERS NtHeaders;
+
+    /* Initialize locals */
+    LocalFile = NULL;
+    ImageBuffer = NULL;
+    FileSize = 0;
+
+    /* Get the size of the image */
+    Status = ImgpGetFileSize(ImageFile, &FileSize);
+    if (!NT_SUCCESS(Status))
+    {
+        return STATUS_FILE_INVALID;
+    }
+
+    /* Allocate a flat buffer for it */
+    Status = BlImgAllocateImageBuffer(&ImageBuffer, BlLoaderData, FileSize, 0);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Read the whole file flat for now */
+    Status = ImgpReadAtFileOffset(ImageFile, FileSize, 0, ImageBuffer, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Build a local file handle */
+    LocalFile = &LocalFileBuffer;
+    LocalFileBuffer.FileName = ImageFile->FileName;
+    LocalFileBuffer.Flags = BL_IMG_MEMORY_FILE | BL_IMG_VALID_FILE;
+    LocalFileBuffer.BaseAddress = ImageBuffer;
+    LocalFileBuffer.FileSize = FileSize;
+
+    /* Get the NT headers of the file */
+    Status = RtlImageNtHeaderEx(0, ImageBuffer, FileSize, &NtHeaders);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Check if we should validate the machine type */
+    if (Flags & BL_LOAD_PE_IMG_CHECK_MACHINE)
+    {
+        /* Is it different than our current machine type? */
+#if _M_AMD64
+        if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
+#else
+        if (NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
+#endif
+        {
+            /* Is it x86 (implying we are x64) ? */
+            if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
+            {
+                /* Return special error code */
+                Status = STATUS_INVALID_IMAGE_WIN_32;
+            }
+            else if (NtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
+            {
+                /* Otherwise, it's x64 but we are x86 */
+                Status = STATUS_INVALID_IMAGE_WIN_64;
+            }
+            else
+            {
+                /* Or it's ARM or something... */
+                Status = STATUS_INVALID_IMAGE_FORMAT;
+            }
+
+            /* Return with the distinguished error code */
+            goto Quickie;
+        }
+    }
+
+    /* Check if we should validate the subsystem */
+    if (Flags & BL_LOAD_PE_IMG_CHECK_SUBSYSTEM)
+    {
+        /* It must be a Windows boot Application */
+        if (NtHeaders->OptionalHeader.Subsystem !=
+            IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
+        {
+            Status = STATUS_INVALID_IMAGE_FORMAT;
+            goto Quickie;
+        }
+    }
+
+    /* Check if we should validate the /INTEGRITYCHECK flag */
+    if (Flags & BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY)
+    {
+        /* Check if it's there */
+        if (!(NtHeaders->OptionalHeader.DllCharacteristics &
+              IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY))
+        {
+            /* Nope, fail otherwise */
+            Status = STATUS_INVALID_IMAGE_FORMAT;
+            goto Quickie;
+        }
+    }
+
+    /* Check if we should compute the image hash */
+    if ((Flags & BL_LOAD_PE_IMG_COMPUTE_HASH) || (Hash))
+    {
+        EfiPrintf(L"No hash support\r\n");
+    }
+
+    /* Read the current base address, if any */
+    VirtualAddress = *ImageBase;
+
+    /* Get the virtual size of the image */
+    VirtualSize = NtHeaders->OptionalHeader.SizeOfImage;
+
+    /* Safely align the virtual size to a page */
+    Status = RtlULongLongAdd(VirtualSize,
+                             PAGE_SIZE - 1,
+                             &VirtualSize);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+    VirtualSize = ALIGN_DOWN_BY(VirtualSize, PAGE_SIZE);
+
+    /* Make sure the image isn't larger than 4GB */
+    if (VirtualSize > ULONG_MAX)
+    {
+        Status = STATUS_INVALID_IMAGE_FORMAT;
+        goto Quickie;
+    }
+
+    /* Check if we have a buffer already */
+    if (Flags & BL_LOAD_IMG_EXISTING_BUFFER)
+    {
+        /* Check if it's too small */
+        if (*ImageSize < VirtualSize)
+        {
+            /* Fail, letting the caller know how big to make it */
+            *ImageSize = VirtualSize;
+            Status = STATUS_BUFFER_TOO_SMALL;
+        }
+    }
+    else
+    {
+        /* Allocate the buffer with the flags and type the caller wants */
+        Status = BlImgAllocateImageBuffer(&VirtualAddress,
+                                          MemoryType,
+                                          VirtualSize,
+                                          Flags);
+    }
+
+    /* Bail out if allocation failed, or existing buffer is too small */
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Read the size of the headers */
+    HeaderSize = NtHeaders->OptionalHeader.SizeOfHeaders;
+    if (VirtualSize < HeaderSize)
+    {
+        /* Bail out if they're bigger than the image! */
+        Status = STATUS_INVALID_IMAGE_FORMAT;
+        goto Quickie;
+    }
+
+    /* Now read the header into the buffer */
+    Status = ImgpReadAtFileOffset(LocalFile, HeaderSize, 0, VirtualAddress, 
NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    /* Get the NT headers of the file */
+    Status = RtlImageNtHeaderEx(0, VirtualAddress, HeaderSize, &NtHeaders);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Quickie;
+    }
+
+    EfiPrintf(L"MORE PE TODO: %lx\r\n", 
NtHeaders->OptionalHeader.AddressOfEntryPoint);
+    EfiStall(100000000);
+
+Quickie:
+    /* Check if we had an image buffer allocated */
+    if ((ImageBuffer) && (FileSize))
+    {
+        /* Free it */
+        BlImgUnallocateImageBuffer(ImageBuffer, FileSize, 0);
+    }
+
+    /* Check if we had a local file handle */
+    if (LocalFile)
+    {
+        /* Close it */
+        ImgpCloseFile(LocalFile);
+    }
+
+    /* Check if this is the failure path */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Check if we had started mapping in the image already */
+        if ((VirtualAddress) && !(Flags & BL_LOAD_PE_IMG_EXISTING_BUFFER))
+        {
+            /* Into a virtual buffer? */
+            if (Flags & BL_LOAD_PE_IMG_VIRTUAL_BUFFER)
+            {
+                /* Unmap and free it */
+                BlMmUnmapVirtualAddressEx(VirtualAddress, VirtualSize);
+                PhysicalAddress.QuadPart = (ULONG_PTR)VirtualAddress;
+                BlMmFreePhysicalPages(PhysicalAddress);
+            }
+            else
+            {
+                /* Into a physical buffer -- free it */
+                EfiPrintf(L"Leaking physical pages\r\n");
+               // MmPapFreePages(VirtualAddress, TRUE);
+            }
+        }
+    }
+
+    /* Return back to caller */
+    return Status;
 }
 
 NTSTATUS
@@ -691,7 +916,7 @@
     }
 
     /* If we are loading a pre-allocated image, make sure we have it */
-    if ((Flags & 4) && (!(*ImageBase) || !(ImageSize)))
+    if ((Flags & BL_LOAD_IMG_EXISTING_BUFFER) && (!(*ImageBase) || 
!(ImageSize)))
     {
         return STATUS_INVALID_PARAMETER;
     }
@@ -707,11 +932,6 @@
                                  ImageSize,
                                  Hash,
                                  Flags);
-    }
-    else
-    {
-        /* For temporary debugging */
-        EfiPrintf(L"Couldn't open file: %lx\r\n", Status);
     }
 
     /* Close the image file and return back to caller */
@@ -750,8 +970,6 @@
     ImageSize = 0;
     ImageBase = NULL;
 
-    EfiPrintf(L"Loading application %p\r\n", BootEntry);
-
     /* Check for "allowed in-memory settings" */
     Status = BlpGetBootOptionIntegerList(BootEntry->BcdData,
                                          
BcdLibraryIntegerList_AllowedInMemorySettings,
@@ -804,12 +1022,10 @@
     }
 
     /* Open the device */
-    EfiPrintf(L"Opening device for path: %s\r\n", Path);
     Status = BlpDeviceOpen(Device,
                            BL_DEVICE_READ_ACCESS,
                            0,
                            &DeviceId);
-    EfiPrintf(L"Device ID: %lx %lx\r\n", Status, DeviceId);
     if (!NT_SUCCESS(Status))
     {
         goto Quickie;


Reply via email to