1874ae09a7004b136480eb588863d3b875c7dfa4
[pithos-ms-client] / trunk / Pithos.ShellExtensions / Overlays / IconOverlayBase.cs
1 using System;
2 using System.Diagnostics;
3 using System.Diagnostics.Contracts;
4 using System.IO;
5
6 using System.ComponentModel.Composition;
7 using Pithos.Interfaces;
8
9 namespace Pithos.ShellExtensions.Overlays
10 {
11
12     public class IconOverlayBase : IShellIconOverlayIdentifier
13     {
14         protected static string PithosPrefix = "0Pithos";
15
16         public string OverlayName { get; private set; }
17         public string IconPath { get; private set; }
18
19         [Import(typeof (IStatusChecker))] 
20         public IStatusChecker StatusChecker;
21         [Import(typeof (IPithosSettings))] 
22         public IPithosSettings Settings;
23
24
25
26         public IconOverlayBase(string iconName)
27         {
28             if (String.IsNullOrWhiteSpace(iconName))
29                 throw new ArgumentNullException("iconName","Empty iconName");
30
31             Debug.WriteLine("Icon Overlay Instance created", LogCategories.ShellOverlays);
32             IoC.Current.Compose(this);
33             
34
35             string overlayName=PithosPrefix + iconName;
36             string iconFile = iconName + "Icon.ico";
37
38
39             var iconsFolder = Settings.IconsPath;
40             var fullPath = Path.Combine(iconsFolder, iconFile);
41
42             OverlayName = overlayName;
43             IconPath = fullPath;
44
45             
46         }
47
48
49         public int IsMemberOf(string path, uint attributes)
50         {
51             if (String.IsNullOrWhiteSpace(path))
52                 throw new ArgumentNullException("path","Empty path");
53
54             Debug.WriteLine(String.Format("ICON Status check for {0} - {1}", path, GetType().Name), LogCategories.ShellOverlays);
55             
56             if (!path.StartsWith(Settings.PithosPath,true,null))
57                 return WinError.S_FALSE;
58
59             var status=StatusChecker.GetFileOverlayStatus(path);
60             var isMember = (PithosPrefix + status == OverlayName);
61             Debug.WriteLine(String.Format("[STATUS] Was {0}, expected {1} for {2}", status, OverlayName,path ), LogCategories.ShellOverlays);
62             return isMember ? WinError.S_OK : WinError.S_FALSE;
63         }
64
65         public int GetOverlayInfo(
66             IntPtr iconFileBuffer,
67             int iconFileBufferSize,
68             out int iconIndex,
69             out uint flags)
70         {
71             Contract.Requires(iconFileBuffer!=IntPtr.Zero);
72             Contract.Requires(iconFileBufferSize>0);
73
74             if (iconFileBuffer == IntPtr.Zero)
75                 throw new ArgumentNullException("iconFileBuffer","iconFileBuffer not initialized");
76             if (iconFileBufferSize<=0)
77                 throw new ArgumentException("iconFileBufferSize", "iconFileBufferSize must be greatere than 0");
78             Debug.WriteLine("Looking for icons", LogCategories.ShellOverlays);
79             Debug.WriteLine(string.Format("ICON file {0}", IconPath), LogCategories.ShellOverlays);
80             
81             int bytesCount = System.Text.Encoding.Unicode.GetByteCount(IconPath);
82             Debug.WriteLine(string.Format(" GetOverlayInfo::{0}", bytesCount), LogCategories.ShellOverlays);
83
84             MarshalHelpers.CopyToBuffer(IconPath, iconFileBuffer, iconFileBufferSize);
85
86             flags = (uint)(ISIOI.ISIOI_ICONFILE);// | ISIOI.ISIOI_ICONINDEX);
87             iconIndex = 0;
88             return WinError.S_OK;
89         }
90
91         public int  GetPriority(out int priority)
92         {
93             Debug.WriteLine("Checking for priority");
94             priority = 0;
95             return WinError.S_OK;
96         }
97
98         
99         public static void RegisterOverlay(Type type,string iconName)
100         {
101             Contract.Requires(type != null);
102             Contract.Requires(!String.IsNullOrWhiteSpace(iconName));
103
104             if (type == null)
105                 throw new ArgumentNullException("type", "type can't be null");
106             if (String.IsNullOrWhiteSpace(iconName))
107                 throw new ArgumentNullException("iconName", "iconName can't be null");
108
109             try
110             {
111                 
112                 ShellExtReg.RegisterIconOverlayIdentifier(type.GUID, iconName);
113
114                 NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST,
115                                              IntPtr.Zero, IntPtr.Zero);
116                 Debug.WriteLine("Registered icon handler");
117             }
118             catch (Exception ex)
119             {
120                 Debug.WriteLine(ex.Message); // Log the error
121                 throw;  // Re-throw the exception
122             }
123         }
124
125         
126         public static void UnregisterOverlay(Type type,string iconName)
127         {
128             Contract.Requires(type!=null);
129             Contract.Requires(!String.IsNullOrWhiteSpace(iconName));
130
131             if (type==null)
132                 throw new ArgumentNullException("type","type can't be null");
133             if (String.IsNullOrWhiteSpace(iconName))
134                 throw new ArgumentNullException("iconName","iconName can't be null");
135             try
136             {                
137                 ShellExtReg.UnregisterIconOverlayIdentifier(type.GUID, iconName);
138                 Debug.WriteLine(String.Format("UnRegistered icon handler {0}:{1}",iconName,type.GUID), LogCategories.ShellOverlays);
139             }
140             catch (Exception ex)
141             {
142                 //Log and rethrow
143                 Trace.TraceError("Failed to unregister overlay {0}:{1} with error {2}",iconName,type.GUID,ex.Message); 
144                 throw;  
145             }
146         }
147     }
148
149 }