1:  /* Compile this one using:
  2:   * $(GCC) -o testsens.exe testsens.c -lole32 -loleaut32 -luuid -lrpcrt4 -mwindows
  3:   */
  4:   
  5:  #define _WIN32_IE 0x0500
  6:  #define _WIN32_WINNT 0x0500
  7:  #define INITGUID
  8:  #include <windows.h>
  9:  #include <rpc.h>
 10:   
 11:  #if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
 12:   
 13:  #include <eventsys.h>
 14:  #include <sensevts.h>
 15:   
 16:  #else
 17:   
 18:  /* Extract relevant typedefs from mingw-w64 headers */
 19:   
 20:  typedef struct {
 21:      DWORD dwSize;
 22:      DWORD dwFlags;
 23:      DWORD dwOutSpeed;
 24:      DWORD dwInSpeed;
 25:  } *LPSENS_QOCINFO;
 26:   
 27:  typedef struct IEnumEventObject IEnumEventObject;
 28:   
 29:  const IID IID_IEnumEventObject;
 30:  typedef struct IEnumEventObjectVtbl {
 31:      BEGIN_INTERFACE
 32:          HRESULT (WINAPI *QueryInterface)(IEnumEventObject *This,REFIID riid,void **ppvObject);
 33:          ULONG (WINAPI *AddRef)(IEnumEventObject *This);
 34:          ULONG (WINAPI *Release)(IEnumEventObject *This);
 35:          HRESULT (WINAPI *Clone)(IEnumEventObject *This,IEnumEventObject **ppInterface);
 36:          HRESULT (WINAPI *Next)(IEnumEventObject *This,ULONG cReqElem,IUnknown **ppInterface,ULONG *cRetElem);
 37:          HRESULT (WINAPI *Reset)(IEnumEventObject *This);
 38:          HRESULT (WINAPI *Skip)(IEnumEventObject *This,ULONG cSkipElem);
 39:      END_INTERFACE
 40:  } IEnumEventObjectVtbl;
 41:  struct IEnumEventObject {
 42:      CONST_VTBL struct IEnumEventObjectVtbl *lpVtbl;
 43:  };
 44:   
 45:   
 46:  typedef struct IEventObjectCollection IEventObjectCollection;
 47:   
 48:  const IID IID_IEventObjectCollection;
 49:  typedef struct IEventObjectCollectionVtbl {
 50:      BEGIN_INTERFACE
 51:          HRESULT (WINAPI *QueryInterface)(IEventObjectCollection *This,REFIID riid,void **ppvObject);
 52:          ULONG (WINAPI *AddRef)(IEventObjectCollection *This);
 53:          ULONG (WINAPI *Release)(IEventObjectCollection *This);
 54:          HRESULT (WINAPI *GetTypeInfoCount)(IEventObjectCollection *This,UINT *pctinfo);
 55:          HRESULT (WINAPI *GetTypeInfo)(IEventObjectCollection *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo);
 56:          HRESULT (WINAPI *GetIDsOfNames)(IEventObjectCollection *This,REFIID riid,LPOLESTR *rgszNames,
 57:                                          UINT cNames,LCID lcid,DISPID *rgDispId);
 58:          HRESULT (WINAPI *Invoke)(IEventObjectCollection *This,DISPID dispIdMember,REFIID riid,LCID lcid,
 59:                                   WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,
 60:                                   EXCEPINFO *pExcepInfo,UINT *puArgErr);
 61:          HRESULT (WINAPI *get__NewEnum)(IEventObjectCollection *This,IUnknown **ppUnkEnum);
 62:          HRESULT (WINAPI *get_Item)(IEventObjectCollection *This,BSTR objectID,VARIANT *pItem);
 63:          HRESULT (WINAPI *get_NewEnum)(IEventObjectCollection *This,IEnumEventObject **ppEnum);
 64:          HRESULT (WINAPI *get_Count)(IEventObjectCollection *This,long *pCount);
 65:          HRESULT (WINAPI *Add)(IEventObjectCollection *This,VARIANT *item,BSTR objectID);
 66:          HRESULT (WINAPI *Remove)(IEventObjectCollection *This,BSTR objectID);
 67:      END_INTERFACE
 68:  } IEventObjectCollectionVtbl;
 69:  struct IEventObjectCollection {
 70:      CONST_VTBL struct IEventObjectCollectionVtbl *lpVtbl;
 71:  };
 72:   
 73:   
 74:  typedef struct IEventSystem IEventSystem;
 75:   
 76:  const IID IID_IEventSystem;
 77:  typedef struct IEventSystemVtbl {
 78:      BEGIN_INTERFACE
 79:          HRESULT (WINAPI *QueryInterface)(IEventSystem *This,REFIID riid,void **ppvObject);
 80:          ULONG (WINAPI *AddRef)(IEventSystem *This);
 81:          ULONG (WINAPI *Release)(IEventSystem *This);
 82:          HRESULT (WINAPI *GetTypeInfoCount)(IEventSystem *This,UINT *pctinfo);
 83:          HRESULT (WINAPI *GetTypeInfo)(IEventSystem *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo);
 84:          HRESULT (WINAPI *GetIDsOfNames)(IEventSystem *This,REFIID riid,LPOLESTR *rgszNames,
 85:                                          UINT cNames,LCID lcid,DISPID *rgDispId);
 86:          HRESULT (WINAPI *Invoke)(IEventSystem *This,DISPID dispIdMember,REFIID riid,LCID lcid,
 87:                                   WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,
 88:                                   EXCEPINFO *pExcepInfo,UINT *puArgErr);
 89:          HRESULT (WINAPI *Query)(IEventSystem *This,BSTR progID,BSTR queryCriteria,int *errorIndex,
 90:                                  IUnknown **ppInterface);
 91:          HRESULT (WINAPI *Store)(IEventSystem *This,BSTR ProgID,IUnknown *pInterface);
 92:          HRESULT (WINAPI *Remove)(IEventSystem *This,BSTR progID,BSTR queryCriteria,int *errorIndex);
 93:          HRESULT (WINAPI *get_EventObjectChangeEventClassID)(IEventSystem *This,BSTR *pbstrEventClassID);
 94:          HRESULT (WINAPI *QueryS)(IEventSystem *This,BSTR progID,BSTR queryCriteria,IUnknown **ppInterface);
 95:          HRESULT (WINAPI *RemoveS)(IEventSystem *This,BSTR progID,BSTR queryCriteria);
 96:      END_INTERFACE
 97:  } IEventSystemVtbl;
 98:  struct IEventSystem {
 99:      CONST_VTBL struct IEventSystemVtbl *lpVtbl;
100:  };
101:   
102:  typedef struct IEventSubscription IEventSubscription;
103:   
104:  const IID IID_IEventSubscription;
105:  typedef struct IEventSubscriptionVtbl {
106:      BEGIN_INTERFACE
107:          HRESULT (WINAPI *QueryInterface)(IEventSubscription *This,REFIID riid,void **ppvObject);
108:          ULONG (WINAPI *AddRef)(IEventSubscription *This);
109:          ULONG (WINAPI *Release)(IEventSubscription *This);
110:          HRESULT (WINAPI *GetTypeInfoCount)(IEventSubscription *This,UINT *pctinfo);
111:          HRESULT (WINAPI *GetTypeInfo)(IEventSubscription *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo);
112:          HRESULT (WINAPI *GetIDsOfNames)(IEventSubscription *This,REFIID riid,LPOLESTR *rgszNames,
113:                                          UINT cNames,LCID lcid,DISPID *rgDispId);
114:          HRESULT (WINAPI *Invoke)(IEventSubscription *This,DISPID dispIdMember,REFIID riid,LCID lcid,
115:                                   WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,
116:                                   EXCEPINFO *pExcepInfo,UINT *puArgErr);
117:          HRESULT (WINAPI *get_SubscriptionID)(IEventSubscription *This,BSTR *pbstrSubscriptionID);
118:          HRESULT (WINAPI *put_SubscriptionID)(IEventSubscription *This,BSTR bstrSubscriptionID);
119:          HRESULT (WINAPI *get_SubscriptionName)(IEventSubscription *This,BSTR *pbstrSubscriptionName);
120:          HRESULT (WINAPI *put_SubscriptionName)(IEventSubscription *This,BSTR bstrSubscriptionName);
121:          HRESULT (WINAPI *get_PublisherID)(IEventSubscription *This,BSTR *pbstrPublisherID);
122:          HRESULT (WINAPI *put_PublisherID)(IEventSubscription *This,BSTR bstrPublisherID);
123:          HRESULT (WINAPI *get_EventClassID)(IEventSubscription *This,BSTR *pbstrEventClassID);
124:          HRESULT (WINAPI *put_EventClassID)(IEventSubscription *This,BSTR bstrEventClassID);
125:          HRESULT (WINAPI *get_MethodName)(IEventSubscription *This,BSTR *pbstrMethodName);
126:          HRESULT (WINAPI *put_MethodName)(IEventSubscription *This,BSTR bstrMethodName);
127:          HRESULT (WINAPI *get_SubscriberCLSID)(IEventSubscription *This,BSTR *pbstrSubscriberCLSID);
128:          HRESULT (WINAPI *put_SubscriberCLSID)(IEventSubscription *This,BSTR bstrSubscriberCLSID);
129:          HRESULT (WINAPI *get_SubscriberInterface)(IEventSubscription *This,IUnknown **ppSubscriberInterface);
130:          HRESULT (WINAPI *put_SubscriberInterface)(IEventSubscription *This,IUnknown *pSubscriberInterface);
131:          HRESULT (WINAPI *get_PerUser)(IEventSubscription *This,WINBOOL *pfPerUser);
132:          HRESULT (WINAPI *put_PerUser)(IEventSubscription *This,WINBOOL fPerUser);
133:          HRESULT (WINAPI *get_OwnerSID)(IEventSubscription *This,BSTR *pbstrOwnerSID);
134:          HRESULT (WINAPI *put_OwnerSID)(IEventSubscription *This,BSTR bstrOwnerSID);
135:          HRESULT (WINAPI *get_Enabled)(IEventSubscription *This,WINBOOL *pfEnabled);
136:          HRESULT (WINAPI *put_Enabled)(IEventSubscription *This,WINBOOL fEnabled);
137:          HRESULT (WINAPI *get_Description)(IEventSubscription *This,BSTR *pbstrDescription);
138:          HRESULT (WINAPI *put_Description)(IEventSubscription *This,BSTR bstrDescription);
139:          HRESULT (WINAPI *get_MachineName)(IEventSubscription *This,BSTR *pbstrMachineName);
140:          HRESULT (WINAPI *put_MachineName)(IEventSubscription *This,BSTR bstrMachineName);
141:          HRESULT (WINAPI *GetPublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue);
142:          HRESULT (WINAPI *PutPublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue);
143:          HRESULT (WINAPI *RemovePublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName);
144:          HRESULT (WINAPI *GetPublisherPropertyCollection)(IEventSubscription *This,IEventObjectCollection **collection);
145:          HRESULT (WINAPI *GetSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue);
146:          HRESULT (WINAPI *PutSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue);
147:          HRESULT (WINAPI *RemoveSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName);
148:          HRESULT (WINAPI *GetSubscriberPropertyCollection)(IEventSubscription *This,IEventObjectCollection **collection);
149:          HRESULT (WINAPI *get_InterfaceID)(IEventSubscription *This,BSTR *pbstrInterfaceID);
150:          HRESULT (WINAPI *put_InterfaceID)(IEventSubscription *This,BSTR bstrInterfaceID);
151:      END_INTERFACE
152:  } IEventSubscriptionVtbl;
153:  struct IEventSubscription {
154:      CONST_VTBL struct IEventSubscriptionVtbl *lpVtbl;
155:  };
156:   
157:  typedef struct ISensNetwork ISensNetwork;
158:   
159:  const IID IID_ISensNetwork;
160:  typedef struct ISensNetworkVtbl {
161:      BEGIN_INTERFACE
162:          HRESULT (WINAPI *QueryInterface)(ISensNetwork *This,REFIID riid,void **ppvObject);
163:          ULONG (WINAPI *AddRef)(ISensNetwork *This);
164:          ULONG (WINAPI *Release)(ISensNetwork *This);
165:          HRESULT (WINAPI *GetTypeInfoCount)(ISensNetwork *This,UINT *pctinfo);
166:          HRESULT (WINAPI *GetTypeInfo)(ISensNetwork *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo);
167:          HRESULT (WINAPI *GetIDsOfNames)(ISensNetwork *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,
168:                                          LCID lcid,DISPID *rgDispId);
169:          HRESULT (WINAPI *Invoke)(ISensNetwork *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,
170:                                   DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr);
171:          HRESULT (WINAPI *ConnectionMade)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType,LPSENS_QOCINFO lpQOCInfo);
172:          HRESULT (WINAPI *ConnectionMadeNoQOCInfo)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType);
173:          HRESULT (WINAPI *ConnectionLost)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType);
174:          HRESULT (WINAPI *DestinationReachable)(ISensNetwork *This,BSTR bstrDestination,BSTR bstrConnection,
175:                                                 ULONG ulType,LPSENS_QOCINFO lpQOCInfo);
176:          HRESULT (WINAPI *DestinationReachableNoQOCInfo)(ISensNetwork *This,BSTR bstrDestination,BSTR bstrConnection,
177:                                                          ULONG ulType);
178:      END_INTERFACE
179:  } ISensNetworkVtbl;
180:  struct ISensNetwork {
181:      CONST_VTBL struct ISensNetworkVtbl *lpVtbl;
182:  };
183:   
184:  #define PROGID_EventSubscription OLESTR("EventSystem.EventSubscription")
185:   
186:  #endif
187:   
188:   
189:  #define AM_CONNECTED WM_APP +1
190:  #define AM_DISCONNECTED WM_APP +2
191:  #define WM_SHELLNOTIFY WM_APP +3
192:  #define ID_TRAY 1000
193:   
194:  #define NUM_ELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
195:   
196:  /* 4E14FB9F-2E22-11D1-9964-00C04FBBB345 */
197:  DEFINE_GUID(IID_IEventSystem, 0x4E14FB9F, 0x2E22, 0x11D1, 0x99, 0x64, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45);
198:   
199:  /* 4A6B0E15-2E38-11D1-9965-00C04FBBB345 */
200:  DEFINE_GUID(IID_IEventSubscription, 0x4A6B0E15, 0x2E38, 0x11D1, 0x99, 0x65, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45);
201:   
202:  /* d597bab1-5b9f-11d1-8dd2-00aa004abd5e */
203:  DEFINE_GUID(IID_ISensNetwork, 0xd597bab1, 0x5b9f, 0x11d1, 0x8d, 0xd2, 0x00, 0xaa, 0x00, 0x4a, 0xbd, 0x5e);
204:   
205:  /* 4E14FBA2-2E22-11D1-9964-00C04FBBB345 */
206:  DEFINE_GUID(CLSID_CEventSystem, 0x4E14FBA2, 0x2E22, 0x11D1, 0x99, 0x64, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45);
207:   
208:  /* 7542e960-79c7-11d1-88f9-0080c7d771bf */
209:  DEFINE_GUID(CLSID_CEventSubscription, 0x7542e960, 0x79c7, 0x11d1, 0x88, 0xf9, 0x00, 0x80, 0xc7, 0xd7, 0x71, 0xbf);
210:   
211:   
212:  static const BSTR
213:  MB2WCHAR (const char* a)
214:  {
215:      static WCHAR b[64];
216:      MultiByteToWideChar (0, 0, a, -1, b, 64);
217:      return b;
218:  }
219:   
220:  static const char* AddCurlyBraces (const char* stringUUID)
221:  {
222:      static char curlyBracedUuidString[64];
223:      int i;
224:      if (!stringUUID)
225:          return NULL;
226:      lstrcpy(curlyBracedUuidString,"{");
227:      i = strlen(curlyBracedUuidString);
228:      lstrcat(curlyBracedUuidString+i,stringUUID);
229:      i = strlen(curlyBracedUuidString);
230:      lstrcat(curlyBracedUuidString+i,"}");
231:      return curlyBracedUuidString;
232:  }
233:   
234:  typedef BOOL (WINAPI* IsNetworkAlive_t) (LPDWORD);// Pour la fonction IsNetworkAlive().
235:   
236:  typedef struct {
237:      ISensNetworkVtbl *lpVtbl;
238:      LONG ref;
239:      HWND hWnd;
240:  } MySensNetwork;
241:   
242:  HRESULT WINAPI MySensNetwork_QueryInterface(ISensNetwork *pISensNetwork, REFIID iid, void ** ppv)
243:  {
244:      *ppv=NULL;
245:   
246:      if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IDispatch) || IsEqualIID(iid, &IID_ISensNetwork))
247:          *ppv=pISensNetwork;
248:   
249:      if (NULL==*ppv)
250:          return ResultFromScode(E_NOINTERFACE);
251:   
252:      //AddRef any interface we'll return.
253:      ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);
254:      return NOERROR;
255:  }
256:   
257:  ULONG WINAPI MySensNetwork_AddRef(ISensNetwork *pISensNetwork)
258:  {
259:      MySensNetwork *pMySensNetwork=(MySensNetwork*)pISensNetwork;
260:      return InterlockedIncrement(&(pMySensNetwork->ref));
261:  }
262:   
263:  ULONG WINAPI MySensNetwork_Release(ISensNetwork *pISensNetwork)
264:  {
265:      MySensNetwork *pMySensNetwork=(MySensNetwork*)pISensNetwork;
266:      ULONG tmp = InterlockedDecrement(&(pMySensNetwork->ref));
267:      return tmp;
268:  }
269:   
270:  HRESULT WINAPI MySensNetwork_GetTypeInfoCount(ISensNetwork *pISensNetwork, UINT *pctinfo)
271:  {
272:      return E_NOTIMPL;
273:  }
274:   
275:  HRESULT WINAPI MySensNetwork_GetTypeInfo(ISensNetwork *pISensNetwork, UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
276:  {
277:      return E_NOTIMPL;
278:  }
279:   
280:  HRESULT WINAPI MySensNetwork_GetIDsOfNames(ISensNetwork *pISensNetwork, REFIID riid,
281:                                             LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
282:  {
283:      return E_NOTIMPL;
284:  }
285:   
286:  HRESULT WINAPI MySensNetwork_Invoke(ISensNetwork *pISensNetwork,DISPID dispIdMember,REFIID riid,
287:                                      LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,
288:                                      EXCEPINFO *pExcepInfo,UINT *puArgErr)
289:  {
290:      return E_NOTIMPL;
291:  }
292:   
293:  HRESULT WINAPI MySensNetwork_ConnectionMade(ISensNetwork *pISensNetwork, BSTR bstrConnection,
294:                                              ULONG ulType, LPSENS_QOCINFO lpQOCInfo)
295:  {
296:      MySensNetwork *pMySensNetwork=(MySensNetwork*)pISensNetwork;
297:      if (ulType) PostMessage(pMySensNetwork->hWnd,AM_CONNECTED,(WPARAM)bstrConnection,0);
298:      return S_OK;
299:  }
300:   
301:  HRESULT WINAPI MySensNetwork_ConnectionMadeNoQOCInfo(ISensNetwork *pISensNetwork,
302:                                                       BSTR bstrConnection,ULONG ulType)
303:  {
304:      return S_OK;
305:  }
306:   
307:  HRESULT WINAPI MySensNetwork_ConnectionLost(ISensNetwork *pISensNetwork,  BSTR bstrConnection, ULONG ulType)
308:  {
309:      MySensNetwork *pMySensNetwork=(MySensNetwork*)pISensNetwork;
310:      if (ulType) PostMessage(pMySensNetwork->hWnd,AM_DISCONNECTED,(WPARAM)bstrConnection,0);
311:      return S_OK;
312:  }
313:   
314:  HRESULT WINAPI MySensNetwork_DestinationReachable(ISensNetwork *pISensNetwork, BSTR bstrDestination,
315:                                                    BSTR bstrConnection,ULONG ulType,
316:                                                    LPSENS_QOCINFO lpQOCInfo)
317:  {
318:      return E_NOTIMPL;
319:  }
320:   
321:  HRESULT WINAPI MySensNetwork_DestinationReachableNoQOCInfo(ISensNetwork *pISensNetwork, BSTR bstrDestination,
322:                                                             BSTR bstrConnection,ULONG ulType)
323:  {
324:      return E_NOTIMPL;
325:  }
326:   
327:  ISensNetworkVtbl MySensNetwork_Vtbl = {
328:      MySensNetwork_QueryInterface,
329:      MySensNetwork_AddRef,
330:      MySensNetwork_Release,
331:      MySensNetwork_GetTypeInfoCount,
332:      MySensNetwork_GetTypeInfo,
333:      MySensNetwork_GetIDsOfNames,
334:      MySensNetwork_Invoke,
335:      MySensNetwork_ConnectionMade,
336:      MySensNetwork_ConnectionMadeNoQOCInfo,
337:      MySensNetwork_ConnectionLost,
338:      MySensNetwork_DestinationReachable,
339:      MySensNetwork_DestinationReachableNoQOCInfo
340:  };
341:   
342:  void MySensNetwork_Init(MySensNetwork **pMySensNetwork, HWND fenet)
343:  {
344:      (*pMySensNetwork) = (MySensNetwork *)malloc(sizeof(MySensNetwork));
345:      (*pMySensNetwork)->lpVtbl = &MySensNetwork_Vtbl;
346:      (*pMySensNetwork)->hWnd = fenet;
347:      (*pMySensNetwork)->ref = 1;
348:  }
349:   
350:  void MySensNetwork_Finalize(MySensNetwork **pMySensNetwork)
351:  {
352:      if (*pMySensNetwork)
353:          free(*pMySensNetwork);
354:      (*pMySensNetwork) = NULL;
355:  }
356:   
357:   
358:  HRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
359:  {
360:      static HICON hIcon[2];
361:      static NOTIFYICONDATA NData;
362:      static HMENU hPopupMenu;
363:      static MySensNetwork *pMySensNetwork = 0;
364:      static IEventSystem *pIEventSystem = 0;
365:      HRESULT res;
366:      int i;
367:      static const char* EventClassID="{D5978620-5B9F-11D1-8DD2-00AA004ABD5E}";
368:      static char* MethodNames[]={
369:          "ConnectionMade",
370:          "ConnectionMadeNoQOCInfo",
371:          "ConnectionLost",
372:          "DestinationReachable",
373:          "DestinationReachableNoQOCInfo"
374:      };
375:      static char* SubscriptionNames[]={
376:          "TSTConnectionMade",
377:          "TSTConnectionMadeNoQOCInfo",
378:          "TSTConnectionLost",
379:          "TSTDestinationReachable",
380:          "TSTDestinationReachableNoQOCInfo"
381:      };
382:      unsigned char* SubscriptionIDs[5] = { 0, 0, 0, 0, 0 };
383:   
384:      switch (message)
385:      {
386:      case WM_NCCREATE:
387:      case WM_NCACTIVATE:
388:          return 1;
389:      case WM_CREATE:
390:      {
391:          DWORD Network;
392:          BOOL alive;
393:          HMODULE hDLL;
394:          IsNetworkAlive_t pIsNetworkAlive;
395:          static IEventSubscription *pIEventSubscription = 0;
396:          res=CoCreateInstance(&CLSID_CEventSystem, 0,CLSCTX_SERVER,&IID_IEventSystem,(LPVOID*)&pIEventSystem);
397:          MySensNetwork_Init(&pMySensNetwork,hwnd);
398:          for (i=0; i<NUM_ELEMENTS(SubscriptionNames); i++)
399:          {
400:              UUID tmp_uuid;
401:              res=CoCreateInstance(&CLSID_CEventSubscription,0, CLSCTX_SERVER,
402:                                   &IID_IEventSubscription,(LPVOID*)&pIEventSubscription);
403:              res=pIEventSubscription->lpVtbl->put_EventClassID(pIEventSubscription,MB2WCHAR(EventClassID));
404:              res=pIEventSubscription->lpVtbl->put_SubscriberInterface(pIEventSubscription,(LPUNKNOWN)pMySensNetwork);
405:              res=pIEventSubscription->lpVtbl->put_MethodName(pIEventSubscription,MB2WCHAR(MethodNames[i]));
406:              res=pIEventSubscription->lpVtbl->put_SubscriptionName(pIEventSubscription,MB2WCHAR(SubscriptionNames[i]));;
407:              if (RPC_S_OK == UuidCreate(&tmp_uuid))
408:                  UuidToString(&tmp_uuid, &SubscriptionIDs[i]);
409:              res=pIEventSubscription->lpVtbl->put_SubscriptionID(pIEventSubscription,
410:                                                                  MB2WCHAR(AddCurlyBraces((const char*)SubscriptionIDs[i])));
411:              res=pIEventSubscription->lpVtbl->put_PerUser(pIEventSubscription,TRUE);
412:              res=pIEventSystem->lpVtbl->Store(pIEventSystem, PROGID_EventSubscription,(LPUNKNOWN)pIEventSubscription);
413:              pIEventSubscription->lpVtbl->Release(pIEventSubscription);
414:              pIEventSubscription=0;
415:          }
416:   
417:          hIcon[0]= LoadIcon(NULL,IDI_INFORMATION);
418:          hIcon[1]= LoadIcon(NULL,IDI_ERROR);
419:   
420:          hDLL=LoadLibrary("sensapi.dll");
421:   
422:          pIsNetworkAlive=(IsNetworkAlive_t) GetProcAddress(hDLL,"IsNetworkAlive");
423:   
424:          NData.cbSize = sizeof(NOTIFYICONDATA);
425:          NData.hWnd = hwnd;
426:          NData.uID = ID_TRAY;
427:          NData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
428:          NData.uCallbackMessage = WM_SHELLNOTIFY;
429:          lstrcpy(NData.szTip,"Connection monitor");
430:          NData.dwState=0;
431:          NData.dwStateMask=0;
432:          NData.szInfo[0]=0;
433:          NData.szInfoTitle[0]=0;
434:          NData.dwInfoFlags=NIIF_INFO;
435:          alive=pIsNetworkAlive(&Network);
436:          NData.hIcon = hIcon[alive ? 0 : 1];
437:          Shell_NotifyIcon(NIM_ADD, &NData);
438:          FreeLibrary(hDLL);
439:          hPopupMenu = CreatePopupMenu();
440:          AppendMenu(hPopupMenu, MF_STRING, 0, "Exit");
441:          SetCursor(LoadCursor(0,IDC_ARROW));
442:          return 0;
443:      }
444:   
445:      case WM_COMMAND:
446:          if (lParam == 0)
447:          {
448:              switch (LOWORD (wParam))
449:              {
450:              case 0: // Click on exit 
451:              {
452:                  int errorIndex;
453:                  int i;
454:                  Shell_NotifyIcon(NIM_DELETE, &NData);
455:                  for (i = 0; i < 5; i++)
456:                  {
457:                      char QueryCriteria[64];
458:                      int length;
459:                      lstrcpy(QueryCriteria,"SubscriptionID=");
460:                      length = strlen(QueryCriteria);
461:                      lstrcat(QueryCriteria+length,(const char*)SubscriptionIDs[i]);
462:                      res = pIEventSystem->lpVtbl->Remove(pIEventSystem,PROGID_EventSubscription,
463:                                                          MB2WCHAR(QueryCriteria),&errorIndex);
464:                  }
465:                  pIEventSystem->lpVtbl->Release(pIEventSystem);
466:                  MySensNetwork_Finalize(&pMySensNetwork);
467:                  PostQuitMessage(0);
468:                  break;
469:              }
470:              default:
471:                  break;
472:              }
473:          }
474:          break;
475:   
476:      case WM_SHELLNOTIFY:
477:          if (wParam == ID_TRAY && lParam==WM_RBUTTONUP)
478:          {
479:              POINT pt;
480:              GetCursorPos(&pt);
481:              SetForegroundWindow(hwnd);
482:              TrackPopupMenu(hPopupMenu, TPM_RIGHTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, 0);
483:          }
484:          break;
485:   
486:      case AM_CONNECTED:
487:          lstrcpy(NData.szInfoTitle,"Connected !");
488:          WideCharToMultiByte(0,0,(WCHAR*)wParam,-1,NData.szInfo,255,0,0);
489:          SysFreeString ((BSTR)wParam);
490:          NData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_INFO;
491:          NData.hIcon = hIcon[0];
492:          Shell_NotifyIcon(NIM_MODIFY, &NData);
493:          NData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
494:          break;
495:   
496:      case AM_DISCONNECTED:
497:          lstrcpy (NData.szInfoTitle,"Disconnected !");
498:          WideCharToMultiByte (0,0,(WCHAR*)wParam,-1,NData.szInfo,255,0,0);
499:          SysFreeString ((BSTR)wParam);
500:          NData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_INFO ;
501:          NData.hIcon = hIcon[1];
502:          Shell_NotifyIcon(NIM_MODIFY, &NData);
503:          NData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;//NIF_INFO;
504:          break;
505:   
506:      default:
507:          break;
508:      }
509:      return 0;
510:  }
511:   
512:  int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmd,int show)
513:  {
514:      WNDCLASS wc={0,WndProc,0,0,hInst,0,0,0,0,"hidden"};
515:      MSG Msg;
516:      CoInitialize(0);
517:      RegisterClass(&wc);
518:      CreateWindow ("hidden","",0,0,0,0,0,0,0,0,0);
519:      while (GetMessage (&Msg, 0, 0, 0))
520:      {
521:          DispatchMessage (&Msg);
522:      }
523:      CoUninitialize ();
524:      return 0;
525:  }
526: