Utilities/IconFactory.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 40 2392f7402fb6
child 384 76f859f4aea1
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Drawing;
    14 using System.Drawing.Imaging;
    15 using System.IO;
    16 using System.Text;
    17 
    18 namespace OpenHardwareMonitor.Utilities {
    19   public class IconFactory {
    20 
    21     private struct BITMAPINFOHEADER {
    22       public uint Size;
    23       public int Width;
    24       public int Height;
    25       public ushort Planes;
    26       public ushort BitCount;
    27       public uint Compression;
    28       public uint SizeImage;
    29       public int XPelsPerMeter;
    30       public int YPelsPerMeter;
    31       public uint ClrUsed;
    32       public uint ClrImportant;
    33 
    34       public BITMAPINFOHEADER(int width, int height, int bitCount) {
    35         this.Size = 40;
    36         this.Width = width;
    37         this.Height = height;
    38         this.Planes = 1;
    39         this.BitCount = (ushort)bitCount;
    40         this.Compression = 0;
    41         this.SizeImage = 0;
    42         this.XPelsPerMeter = 0;
    43         this.YPelsPerMeter = 0;
    44         this.ClrUsed = 0;
    45         this.ClrImportant = 0;
    46       }
    47 
    48       public void Write(BinaryWriter bw) {
    49         bw.Write(Size);
    50 			  bw.Write(Width);
    51 			  bw.Write(Height);
    52 			  bw.Write(Planes);
    53 			  bw.Write(BitCount);
    54 			  bw.Write(Compression);
    55 			  bw.Write(SizeImage);
    56 			  bw.Write(XPelsPerMeter);
    57 			  bw.Write(YPelsPerMeter);
    58 			  bw.Write(ClrUsed);
    59 			  bw.Write(ClrImportant);
    60       }
    61     }
    62 
    63     private struct ICONIMAGE {
    64       public BITMAPINFOHEADER Header;
    65       public byte[] Colors;
    66       public byte[] XOR;
    67       public byte[] AND;
    68 
    69       public ICONIMAGE(int width, int height, byte[] colors) {
    70         this.Header = new BITMAPINFOHEADER(width, height << 1, 
    71           (8 * colors.Length) / (width * height));
    72         this.Colors = colors;
    73         int maskSize = (width * height) >> 3;
    74         this.XOR = new byte[maskSize];
    75         this.AND = new byte[maskSize];
    76       }
    77 
    78       public void Write(BinaryWriter bw) {
    79         Header.Write(bw);
    80         int stride = Header.Width << 2;
    81         for (int i = (Header.Height >> 1) - 1; i >= 0; i--)
    82           bw.Write(Colors, i * stride, stride);
    83         bw.Write(XOR);        
    84         bw.Write(AND);
    85       }
    86     }
    87 
    88     private struct ICONDIRENTRY {
    89       public byte Width;
    90       public byte Height;
    91       public byte ColorCount;
    92       public byte Reserved;
    93       public ushort Planes;
    94       public ushort BitCount;
    95       public uint BytesInRes;
    96       public uint ImageOffset;
    97 
    98       public ICONDIRENTRY(ICONIMAGE image, int imageOffset) {
    99         this.Width = (byte)image.Header.Width;
   100         this.Height = (byte)(image.Header.Height >> 1);
   101         this.ColorCount = 0;
   102         this.Reserved = 0;
   103         this.Planes = image.Header.Planes;
   104         this.BitCount = image.Header.BitCount;
   105         this.BytesInRes = (uint)(image.Header.Size +
   106           image.Colors.Length + image.XOR.Length + image.AND.Length);
   107         this.ImageOffset = (uint)imageOffset;
   108       }
   109 
   110       public void Write(BinaryWriter bw) {
   111         bw.Write(Width);
   112         bw.Write(Height);
   113         bw.Write(ColorCount);
   114         bw.Write(Reserved);
   115         bw.Write(Planes);
   116         bw.Write(BitCount);
   117         bw.Write(BytesInRes);
   118         bw.Write(ImageOffset);
   119       }
   120 
   121       public uint Size {
   122         get { return 16; }
   123       }
   124     }
   125 
   126     private struct ICONDIR {
   127       public ushort Reserved;
   128       public ushort Type;
   129       public ushort Count;
   130       public ICONDIRENTRY[] Entries;
   131 
   132       public ICONDIR(ICONDIRENTRY[] entries) {
   133         this.Reserved = 0;
   134         this.Type = 1;
   135         this.Count = (ushort)entries.Length;
   136         this.Entries = entries;
   137       }
   138 
   139       public void Write(BinaryWriter bw) {
   140         bw.Write(Reserved);
   141         bw.Write(Type);
   142         bw.Write(Count);
   143         for (int i = 0; i < Entries.Length; i++)
   144           Entries[i].Write(bw);
   145       }
   146 
   147       public uint Size {
   148         get { return (uint)(6 + Entries.Length * 
   149           (Entries.Length > 0 ? Entries[0].Size : 0)); } 
   150       }
   151     }
   152 	
   153     public static Icon Create(byte[] colors, int width, int height, 
   154       PixelFormat format) {
   155       if (format != PixelFormat.Format32bppArgb)
   156         throw new NotImplementedException();
   157 
   158       ICONIMAGE image = new ICONIMAGE(width, height, colors);
   159       ICONDIR dir = new ICONDIR(
   160         new ICONDIRENTRY[] { new ICONDIRENTRY(image, 0) } );
   161       dir.Entries[0].ImageOffset = dir.Size;
   162 
   163       Icon icon;
   164       using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) {
   165 				dir.Write(bw);
   166         image.Write(bw);
   167 
   168 				bw.BaseStream.Position = 0;
   169         icon = new Icon(bw.BaseStream);
   170 			}
   171 
   172       return icon;
   173     }
   174 
   175   }
   176 }