[CLT2012]
[reactos.git] / ntoskrnl / inbv / inbv.c
index 52cc710..dc5f241 100644 (file)
 KSPIN_LOCK BootDriverLock;
 KIRQL InbvOldIrql;
 INBV_DISPLAY_STATE InbvDisplayState;
-BOOLEAN InbvBootDriverInstalled;
-BOOLEAN InbvDisplayDebugStrings;
+BOOLEAN InbvBootDriverInstalled = FALSE;
+BOOLEAN InbvDisplayDebugStrings = FALSE;
 INBV_DISPLAY_STRING_FILTER InbvDisplayFilter;
 ULONG ProgressBarLeft, ProgressBarTop;
-BOOLEAN ShowProgressBar;
+BOOLEAN ShowProgressBar = FALSE;
 INBV_PROGRESS_STATE InbvProgressState;
 INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters;
 ULONG ResourceCount;
 PUCHAR ResourceList[64];
-BOOLEAN SysThreadCreated;
+BOOLEAN SysThreadCreated = FALSE;
 ROT_BAR_TYPE RotBarSelection;
 ULONG PltRotBarStatus;
 BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
@@ -28,6 +28,7 @@ BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
 
 PVOID
 NTAPI
+INIT_FUNCTION
 FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                    IN ULONG ResourceId)
 {
@@ -37,7 +38,6 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
     LDR_RESOURCE_INFO ResourceInfo;
-    ULONG Size;
     NTSTATUS Status;
     PVOID Data = NULL;
 
@@ -64,7 +64,7 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
     if (NextEntry != ListHead)
     {
         /* Try to find the resource */
-        ResourceInfo.Type = 2;
+        ResourceInfo.Type = 2; //RT_BITMAP;
         ResourceInfo.Name = ResourceId;
         ResourceInfo.Language = 0;
         Status = LdrFindResource_U(LdrEntry->DllBase,
@@ -74,10 +74,15 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
         if (NT_SUCCESS(Status))
         {
             /* Access the resource */
+            ULONG Size = 0;
             Status = LdrAccessResource(LdrEntry->DllBase,
                                        ResourceDataEntry,
                                        &Data,
                                        &Size);
+            if ((Data) && (ResourceId < 3))
+            {
+                KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, Size);
+            }
             if (!NT_SUCCESS(Status)) Data = NULL;
         }
     }
@@ -88,6 +93,7 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
 
 BOOLEAN
 NTAPI
+INIT_FUNCTION
 InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                      IN ULONG Count)
 {
@@ -115,8 +121,8 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
         VidResetDisplay(CustomLogo);
         
         /* Find bitmap resources in the kernel */
-        ResourceCount = Count;
-        for (i = 0; i < Count; i++)
+        ResourceCount = min(IDB_CLUSTER_SERVER, Count);
+        for (i = 1; i <= Count; i++)
         {
             /* Do the lookup */
             ResourceList[i] = FindBitmapResource(LoaderBlock, i);
@@ -134,31 +140,43 @@ VOID
 NTAPI
 InbvAcquireLock(VOID)
 {
-    /* Check if we're below dispatch level */
-    InbvOldIrql = KeGetCurrentIrql();
-    if (InbvOldIrql < DISPATCH_LEVEL)
+    KIRQL OldIrql;
+
+    /* Check if we're at dispatch level or lower */
+    OldIrql = KeGetCurrentIrql();
+    if (OldIrql <= DISPATCH_LEVEL)
     {
+        /* Loop until the lock is free */
+        while (!KeTestSpinLock(&BootDriverLock));
+
         /* Raise IRQL to dispatch level */
-        KeRaiseIrql(DISPATCH_LEVEL, &InbvOldIrql);
+        KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
     }
 
     /* Acquire the lock */
     KiAcquireSpinLock(&BootDriverLock);
+    InbvOldIrql = OldIrql;
 }
 
 VOID
 NTAPI
 InbvReleaseLock(VOID)
 {
+    KIRQL OldIrql;
+
+    /* Capture the old IRQL */
+    OldIrql = InbvOldIrql;
+
     /* Release the driver lock */
     KiReleaseSpinLock(&BootDriverLock);
 
-    /* If we were below dispatch level, lower IRQL back */
-    if (InbvOldIrql < DISPATCH_LEVEL) KeLowerIrql(InbvOldIrql);
+    /* If we were at dispatch level or lower, restore the old IRQL */
+    if (InbvOldIrql <= DISPATCH_LEVEL) KeLowerIrql(OldIrql);
 }
 
 VOID
 NTAPI
+INIT_FUNCTION
 InbvEnableBootDriver(IN BOOLEAN Enable)
 {
     /* Check if we're installed */
@@ -248,8 +266,13 @@ InbvDisplayString(IN PCHAR String)
         /* Make sure we're installed and display the string */
         if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
 
-        /* Call Headless (We don't support headless for now)
-        HeadlessDispatch(DISPLAY_STRING); */
+        /* Print the string on the EMS port */
+               HeadlessDispatch(
+                       HeadlessCmdPutString,
+                       String,
+                       strlen(String) + sizeof(ANSI_NULL),
+                       NULL,
+                       NULL);
 
         /* Release the lock */
         InbvReleaseLock();
@@ -388,6 +411,7 @@ InbvSolidColorFill(IN ULONG Left,
 
 VOID
 NTAPI
+INIT_FUNCTION
 InbvUpdateProgressBar(IN ULONG Progress)
 {
     ULONG FillCount, BoundedProgress;
@@ -503,6 +527,7 @@ InbvSetProgressBarSubset(IN ULONG Floor,
 
 VOID
 NTAPI
+INIT_FUNCTION
 InbvIndicateProgress(VOID)
 {
     ULONG Percentage;
@@ -550,9 +575,10 @@ NtDisplayString(IN PUNICODE_STRING DisplayString)
 
 VOID
 NTAPI
-DisplayBootBitmap(IN BOOLEAN SosMode)
+INIT_FUNCTION
+DisplayBootBitmap(IN BOOLEAN TextMode)
 {
-    PVOID Header, Band, Bar, Text, Screen;
+    PVOID Header, Band, Text, Screen;
     ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
     UCHAR Buffer[64];
     
@@ -561,13 +587,13 @@ DisplayBootBitmap(IN BOOLEAN SosMode)
     {
         /* Reset the progress bar */
         InbvAcquireLock();
-        RotBarSelection = 0;
+        RotBarSelection = RB_UNSPECIFIED;
         InbvReleaseLock();
     }
 
-    /* Check if this is SOS mode */
+    /* Check if this is text mode */
     ShowProgressBar = FALSE;
-    if (SosMode)
+    if (TextMode)
     {
         /* Check if this is a server OS */
         if (SharedUserData->NtProductType == NtProductWinNt)
@@ -615,7 +641,7 @@ DisplayBootBitmap(IN BOOLEAN SosMode)
         if (SharedUserData->NtProductType == NtProductWinNt)
         {
             /* Workstation product, display appropriate status bar color */
-            Bar = InbvGetResourceAddress(IDB_BAR_PRO);
+            InbvGetResourceAddress(IDB_BAR_PRO);
         }
         else
         {
@@ -637,7 +663,7 @@ DisplayBootBitmap(IN BOOLEAN SosMode)
             }
             
             /* Server product, display appropriate status bar color */
-            Bar = InbvGetResourceAddress(IDB_BAR_SERVER);
+            InbvGetResourceAddress(IDB_BAR_SERVER);
         }
         
         /* Make sure we had a logo */
@@ -670,6 +696,9 @@ DisplayBootBitmap(IN BOOLEAN SosMode)
           
           /* Draw the progress bar bit */
 //          if (Bar) InbvBitBlt(Bar, 0, 0);
+
+          /* Set filter which will draw text display if needed */
+          InbvInstallDisplayStringFilter(DisplayFilter);
     }
 
     /* Do we have a system thread? */
@@ -685,6 +714,31 @@ DisplayBootBitmap(IN BOOLEAN SosMode)
 
 VOID
 NTAPI
+INIT_FUNCTION
+DisplayFilter(PCHAR *String)
+{
+    /* Windows hack to skip first dots */
+    static BOOLEAN DotHack = TRUE;
+
+    /* If "." is given set *String to empty string */
+    if(DotHack && strcmp(*String, ".") == 0)
+        *String = "";
+
+    if(**String)
+    {
+        /* Remove the filter */
+        InbvInstallDisplayStringFilter(NULL);
+        
+        DotHack = FALSE;
+
+        /* Draw text screen */
+        DisplayBootBitmap(TRUE);
+    }
+}
+
+VOID
+NTAPI
+INIT_FUNCTION
 FinalizeBootLogo(VOID)
 {
     /* Acquire lock and check the display state */