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