Replaced object load and update with direct HQL execution to resolve database locks...
[pithos-ms-client] / trunk / Pithos.Core / NativeMethods.cs
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Runtime.InteropServices;
6 using System.Text;
7
8 namespace Pithos.Core
9 {
10     #region Enums & Structs
11
12     #region enum HChangeNotifyEventID
13     /// <summary>
14     /// Describes the event that has occurred. 
15     /// Typically, only one event is specified at a time. 
16     /// If more than one event is specified, the values contained 
17     /// in the <i>dwItem1</i> and <i>dwItem2</i> 
18     /// parameters must be the same, respectively, for all specified events. 
19     /// This parameter can be one or more of the following values. 
20     /// </summary>
21     /// <remarks>
22     /// <para><b>Windows NT/2000/XP:</b> <i>dwItem2</i> contains the index 
23     /// in the system image list that has changed. 
24     /// <i>dwItem1</i> is not used and should be <see langword="null"/>.</para>
25     /// <para><b>Windows 95/98:</b> <i>dwItem1</i> contains the index 
26     /// in the system image list that has changed. 
27     /// <i>dwItem2</i> is not used and should be <see langword="null"/>.</para>
28     /// </remarks>
29     [Flags]
30     public enum HChangeNotifyEventID
31     {
32         /// <summary>
33         /// All events have occurred. 
34         /// </summary>
35         SHCNE_ALLEVENTS = 0x7FFFFFFF,
36
37         /// <summary>
38         /// A file type association has changed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
39         /// must be specified in the <i>uFlags</i> parameter. 
40         /// <i>dwItem1</i> and <i>dwItem2</i> are not used and must be <see langword="null"/>. 
41         /// </summary>
42         SHCNE_ASSOCCHANGED = 0x08000000,
43
44         /// <summary>
45         /// The attributes of an item or folder have changed. 
46         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
47         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
48         /// <i>dwItem1</i> contains the item or folder that has changed. 
49         /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
50         /// </summary>
51         SHCNE_ATTRIBUTES = 0x00000800,
52
53         /// <summary>
54         /// A nonfolder item has been created. 
55         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
56         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
57         /// <i>dwItem1</i> contains the item that was created. 
58         /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
59         /// </summary>
60         SHCNE_CREATE = 0x00000002,
61
62         /// <summary>
63         /// A nonfolder item has been deleted. 
64         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
65         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
66         /// <i>dwItem1</i> contains the item that was deleted. 
67         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
68         /// </summary>
69         SHCNE_DELETE = 0x00000004,
70
71         /// <summary>
72         /// A drive has been added. 
73         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
74         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
75         /// <i>dwItem1</i> contains the root of the drive that was added. 
76         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
77         /// </summary>
78         SHCNE_DRIVEADD = 0x00000100,
79
80         /// <summary>
81         /// A drive has been added and the Shell should create a new window for the drive. 
82         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
83         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
84         /// <i>dwItem1</i> contains the root of the drive that was added. 
85         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
86         /// </summary>
87         SHCNE_DRIVEADDGUI = 0x00010000,
88
89         /// <summary>
90         /// A drive has been removed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
91         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
92         /// <i>dwItem1</i> contains the root of the drive that was removed.
93         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
94         /// </summary>
95         SHCNE_DRIVEREMOVED = 0x00000080,
96
97         /// <summary>
98         /// Not currently used. 
99         /// </summary>
100         SHCNE_EXTENDED_EVENT = 0x04000000,
101
102         /// <summary>
103         /// The amount of free space on a drive has changed. 
104         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
105         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
106         /// <i>dwItem1</i> contains the root of the drive on which the free space changed.
107         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
108         /// </summary>
109         SHCNE_FREESPACE = 0x00040000,
110
111         /// <summary>
112         /// Storage media has been inserted into a drive. 
113         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
114         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
115         /// <i>dwItem1</i> contains the root of the drive that contains the new media. 
116         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
117         /// </summary>
118         SHCNE_MEDIAINSERTED = 0x00000020,
119
120         /// <summary>
121         /// Storage media has been removed from a drive. 
122         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
123         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
124         /// <i>dwItem1</i> contains the root of the drive from which the media was removed. 
125         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
126         /// </summary>
127         SHCNE_MEDIAREMOVED = 0x00000040,
128
129         /// <summary>
130         /// A folder has been created. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
131         /// or <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
132         /// <i>dwItem1</i> contains the folder that was created. 
133         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
134         /// </summary>
135         SHCNE_MKDIR = 0x00000008,
136
137         /// <summary>
138         /// A folder on the local computer is being shared via the network. 
139         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
140         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
141         /// <i>dwItem1</i> contains the folder that is being shared. 
142         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
143         /// </summary>
144         SHCNE_NETSHARE = 0x00000200,
145
146         /// <summary>
147         /// A folder on the local computer is no longer being shared via the network. 
148         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
149         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
150         /// <i>dwItem1</i> contains the folder that is no longer being shared. 
151         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
152         /// </summary>
153         SHCNE_NETUNSHARE = 0x00000400,
154
155         /// <summary>
156         /// The name of a folder has changed. 
157         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
158         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
159         /// <i>dwItem1</i> contains the previous pointer to an item identifier list (PIDL) or name of the folder. 
160         /// <i>dwItem2</i> contains the new PIDL or name of the folder. 
161         /// </summary>
162         SHCNE_RENAMEFOLDER = 0x00020000,
163
164         /// <summary>
165         /// The name of a nonfolder item has changed. 
166         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
167         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
168         /// <i>dwItem1</i> contains the previous PIDL or name of the item. 
169         /// <i>dwItem2</i> contains the new PIDL or name of the item. 
170         /// </summary>
171         SHCNE_RENAMEITEM = 0x00000001,
172
173         /// <summary>
174         /// A folder has been removed. 
175         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
176         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
177         /// <i>dwItem1</i> contains the folder that was removed. 
178         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
179         /// </summary>
180         SHCNE_RMDIR = 0x00000010,
181
182         /// <summary>
183         /// The computer has disconnected from a server. 
184         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
185         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
186         /// <i>dwItem1</i> contains the server from which the computer was disconnected. 
187         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
188         /// </summary>
189         SHCNE_SERVERDISCONNECT = 0x00004000,
190
191         /// <summary>
192         /// The contents of an existing folder have changed, 
193         /// but the folder still exists and has not been renamed. 
194         /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
195         /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
196         /// <i>dwItem1</i> contains the folder that has changed. 
197         /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
198         /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or 
199         /// SHCNE_RENAMEFOLDER, respectively, instead. 
200         /// </summary>
201         SHCNE_UPDATEDIR = 0x00001000,
202
203         SHCNE_UPDATEITEM = 0x00002000,
204
205         /// <summary>
206         /// An image in the system image list has changed. 
207         /// <see cref="HChangeNotifyFlags.SHCNF_DWORD"/> must be specified in <i>uFlags</i>. 
208         /// </summary>
209         SHCNE_UPDATEIMAGE = 0x00008000,
210
211     }
212     #endregion // enum HChangeNotifyEventID
213
214     #region public enum HChangeNotifyFlags
215     /// <summary>
216     /// Flags that indicate the meaning of the <i>dwItem1</i> and <i>dwItem2</i> parameters. 
217     /// The uFlags parameter must be one of the following values.
218     /// </summary>
219     [Flags]
220     public enum HChangeNotifyFlags
221     {
222         /// <summary>
223         /// The <i>dwItem1</i> and <i>dwItem2</i> parameters are DWORD values. 
224         /// </summary>
225         SHCNF_DWORD = 0x0003,
226         /// <summary>
227         /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of ITEMIDLIST structures that 
228         /// represent the item(s) affected by the change. 
229         /// Each ITEMIDLIST must be relative to the desktop folder. 
230         /// </summary>
231         SHCNF_IDLIST = 0x0000,
232         /// <summary>
233         /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
234         /// maximum length MAX_PATH that contain the full path names 
235         /// of the items affected by the change. 
236         /// </summary>
237         SHCNF_PATHA = 0x0001,
238         /// <summary>
239         /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
240         /// maximum length MAX_PATH that contain the full path names 
241         /// of the items affected by the change. 
242         /// </summary>
243         SHCNF_PATHW = 0x0005,
244         /// <summary>
245         /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
246         /// represent the friendly names of the printer(s) affected by the change. 
247         /// </summary>
248         SHCNF_PRINTERA = 0x0002,
249         /// <summary>
250         /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
251         /// represent the friendly names of the printer(s) affected by the change. 
252         /// </summary>
253         SHCNF_PRINTERW = 0x0006,
254         /// <summary>
255         /// The function should not return until the notification 
256         /// has been delivered to all affected components. 
257         /// As this flag modifies other data-type flags, it cannot by used by itself.
258         /// </summary>
259         SHCNF_FLUSH = 0x1000,
260         /// <summary>
261         /// The function should begin delivering notifications to all affected components 
262         /// but should return as soon as the notification process has begun. 
263         /// As this flag modifies other data-type flags, it cannot by used by itself.
264         /// </summary>
265         SHCNF_FLUSHNOWAIT = 0x2000
266     }
267     #endregion // enum HChangeNotifyFlags
268
269
270     #endregion
271
272     public static class NativeMethods
273     {
274         [DllImport("shell32.dll")]
275         public static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
276                                            HChangeNotifyFlags uFlags,
277                                            IntPtr dwItem1,
278                                            IntPtr dwItem2);
279
280         public static void RaiseChangeNotification(string path)
281         {
282             if (String.IsNullOrWhiteSpace(path))
283                 throw new ArgumentNullException("path", "The path parameter must not be emtpy");
284
285             if (!Directory.Exists(path) && !File.Exists(path))
286                 return;
287
288
289             IntPtr pathPointer = Marshal.StringToCoTaskMemAuto(path);
290
291             try
292             {
293                 NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM,
294                                              HChangeNotifyFlags.SHCNF_PATHW | HChangeNotifyFlags.SHCNF_FLUSHNOWAIT,
295                                              pathPointer, IntPtr.Zero);
296             }
297             finally
298             {
299                 Marshal.FreeHGlobal(pathPointer);
300             }
301
302         }
303     }
304
305
306 }