[NETSHELL]
[reactos.git] / reactos / dll / win32 / netshell / lanstatusui.cpp
1 #include "precomp.h"
2
3 WINE_DEFAULT_DEBUG_CHANNEL (shell);
4
5 /// CLSID
6 /// HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{7007ACCF-3202-11D1-AAD2-00805FC1270E}
7 // IID B722BCCB-4E68-101B-A2BC-00AA00404770
8
9 #define WM_SHOWSTATUSDLG (WM_USER+10)
10
11 typedef struct tagNotificationItem
12 {
13 struct tagNotificationItem *pNext;
14 CLSID guidItem;
15 UINT uID;
16 HWND hwndDlg;
17 INetConnection *pNet;
18 } NOTIFICATION_ITEM;
19
20 typedef struct
21 {
22 INetConnection *pNet;
23 HWND hwndStatusDlg; /* LanStatusDlg window */
24 HWND hwndDlg; /* status dialog window */
25 DWORD dwAdapterIndex;
26 UINT_PTR nIDEvent;
27 UINT DHCPEnabled;
28 DWORD dwInOctets;
29 DWORD dwOutOctets;
30 DWORD IpAddress;
31 DWORD SubnetMask;
32 DWORD Gateway;
33 UINT uID;
34 UINT Status;
35 } LANSTATUSUI_CONTEXT;
36
37 class CLanStatus :
38 public IOleCommandTarget
39 {
40 public:
41 CLanStatus();
42
43 // IUnknown
44 virtual HRESULT WINAPI QueryInterface(REFIID riid, LPVOID *ppvOut);
45 virtual ULONG WINAPI AddRef();
46 virtual ULONG WINAPI Release();
47
48 // IOleCommandTarget
49 virtual HRESULT WINAPI QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText);
50 virtual HRESULT WINAPI Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
51
52 private:
53 HRESULT InitializeNetTaskbarNotifications();
54 HRESULT ShowStatusDialogByCLSID(const GUID *pguidCmdGroup);
55
56 INetConnectionManager *lpNetMan;
57 LONG ref;
58 NOTIFICATION_ITEM *pHead;
59 };
60
61 CLanStatus::CLanStatus()
62 {
63 ref = 0;
64 lpNetMan = NULL;
65 pHead = NULL;
66 }
67
68 VOID
69 UpdateLanStatusUiDlg(
70 HWND hwndDlg,
71 MIB_IFROW *IfEntry,
72 LANSTATUSUI_CONTEXT *pContext)
73 {
74 WCHAR szFormat[MAX_PATH] = {0};
75 WCHAR szBuffer[MAX_PATH] = {0};
76 SYSTEMTIME TimeConnected;
77 DWORD DurationSeconds;
78 WCHAR Buffer[100];
79 WCHAR DayBuffer[30];
80 WCHAR LocBuffer[50];
81
82 #if 0
83 ULONGLONG Ticks;
84 #else
85 DWORD Ticks;
86 #endif
87
88 if (IfEntry->dwSpeed < 1000)
89 {
90 if (LoadStringW(netshell_hInstance, IDS_FORMAT_BIT, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
91 {
92 swprintf(szBuffer, szFormat, IfEntry->dwSpeed);
93 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer);
94 }
95 }
96 else if (IfEntry->dwSpeed < 1000000)
97 {
98 if (LoadStringW(netshell_hInstance, IDS_FORMAT_KBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
99 {
100 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000);
101 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer);
102 }
103 }
104 else if (IfEntry->dwSpeed < 1000000000)
105 {
106 if (LoadStringW(netshell_hInstance, IDS_FORMAT_MBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
107 {
108 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000000);
109 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer);
110 }
111 }
112 else
113 {
114 if (LoadStringW(netshell_hInstance, IDS_FORMAT_GBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
115 {
116 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000000000);
117 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer);
118 }
119 }
120
121 if (StrFormatByteSizeW(IfEntry->dwInOctets, szBuffer, sizeof(szFormat)/sizeof(WCHAR)))
122 {
123 SendDlgItemMessageW(hwndDlg, IDC_RECEIVED, WM_SETTEXT, 0, (LPARAM)szBuffer);
124 }
125
126 if (StrFormatByteSizeW(IfEntry->dwOutOctets, szBuffer, sizeof(szFormat)/sizeof(WCHAR)))
127 {
128 SendDlgItemMessageW(hwndDlg, IDC_SEND, WM_SETTEXT, 0, (LPARAM)szBuffer);
129 }
130
131 #if 0
132 Ticks = GetTickCount64();
133 #else
134 Ticks = GetTickCount();
135 #endif
136
137 DurationSeconds = Ticks / 1000;
138 TimeConnected.wSecond = (DurationSeconds % 60);
139 TimeConnected.wMinute = (DurationSeconds / 60) % 60;
140 TimeConnected.wHour = (DurationSeconds / (60 * 60)) % 24;
141 TimeConnected.wDay = DurationSeconds / (60 * 60 * 24);
142
143 if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &TimeConnected, L"HH':'mm':'ss", LocBuffer, sizeof(LocBuffer) / sizeof(LocBuffer[0])))
144 return;
145
146 if (!TimeConnected.wDay)
147 {
148 SendDlgItemMessageW(hwndDlg, IDC_DURATION, WM_SETTEXT, 0, (LPARAM)LocBuffer);
149 }
150 else
151 {
152 if (TimeConnected.wDay == 1)
153 {
154 if (!LoadStringW(netshell_hInstance, IDS_DURATION_DAY, DayBuffer, sizeof(DayBuffer) / sizeof(DayBuffer[0])))
155 DayBuffer[0] = L'\0';
156 }
157 else
158 {
159 if (!LoadStringW(netshell_hInstance, IDS_DURATION_DAYS, DayBuffer, sizeof(DayBuffer) / sizeof(DayBuffer[0])))
160 DayBuffer[0] = L'\0';
161 }
162 swprintf(Buffer, DayBuffer, TimeConnected.wDay, LocBuffer);
163 SendDlgItemMessageW(hwndDlg, IDC_DURATION, WM_SETTEXT, 0, (LPARAM)Buffer);
164 }
165
166 }
167
168 VOID
169 UpdateLanStatus(HWND hwndDlg, LANSTATUSUI_CONTEXT * pContext)
170 {
171 MIB_IFROW IfEntry;
172 HICON hIcon, hOldIcon = NULL;
173 NOTIFYICONDATAW nid;
174 NETCON_PROPERTIES * pProperties = NULL;
175
176 ZeroMemory(&IfEntry, sizeof(IfEntry));
177 IfEntry.dwIndex = pContext->dwAdapterIndex;
178 if(GetIfEntry(&IfEntry) != NO_ERROR)
179 {
180 return;
181 }
182
183 hIcon = NULL;
184 if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
185 {
186 if (pContext->dwInOctets == IfEntry.dwInOctets && pContext->dwOutOctets == IfEntry.dwOutOctets && pContext->Status != 0)
187 {
188 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
189 pContext->Status = 0;
190 }
191 else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status != 1)
192 {
193 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANSREC), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
194 pContext->Status = 1;
195 }
196 else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->Status != 2)
197 {
198 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_REC), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
199 pContext->Status = 2;
200 }
201 else if (pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status != 3)
202 {
203 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANS), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
204 pContext->Status = 3;
205 }
206 }
207 else if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_UNREACHABLE || IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_DISCONNECTED)
208 {
209 if (pContext->Status != 4)
210 {
211 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
212 pContext->Status = 4;
213 }
214 }
215 else if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_NON_OPERATIONAL)
216 {
217 if (pContext->Status != 5)
218 {
219 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
220 pContext->Status = 5;
221 }
222 }
223
224 if (hwndDlg && hIcon)
225 {
226 hOldIcon = (HICON)SendDlgItemMessageW(hwndDlg, IDC_NETSTAT, STM_SETICON, (WPARAM)hIcon, 0);
227 if (hOldIcon)
228 DestroyIcon(hOldIcon);
229 }
230
231 ZeroMemory(&nid, sizeof(nid));
232 nid.cbSize = sizeof(nid);
233 nid.uID = pContext->uID;
234 nid.hWnd = pContext->hwndStatusDlg;
235 nid.uVersion = 3;
236
237 if (pContext->pNet->GetProperties(&pProperties) == S_OK)
238 {
239 if (pProperties->dwCharacter & NCCF_SHOW_ICON)
240 {
241 if (hwndDlg)
242 nid.hIcon = (HICON)CopyImage(hIcon, IMAGE_ICON, 16, 16, 0);
243 else
244 nid.hIcon = hIcon;
245
246 if (nid.hIcon)
247 nid.uFlags |= NIF_ICON;
248
249 nid.uFlags |= NIF_STATE;
250 nid.dwState = 0;
251 nid.dwStateMask = NIS_HIDDEN;
252
253 if (pProperties->pszwName)
254 {
255 if (wcslen(pProperties->pszwName) * sizeof(WCHAR) < sizeof(nid.szTip))
256 {
257 nid.uFlags |= NIF_TIP;
258 wcscpy(nid.szTip, pProperties->pszwName);
259 }
260 else
261 {
262 CopyMemory(nid.szTip, pProperties->pszwName, sizeof(nid.szTip) - sizeof(WCHAR));
263 nid.szTip[(sizeof(nid.szTip)/sizeof(WCHAR))-1] = L'\0';
264 nid.uFlags |= NIF_TIP;
265 }
266 }
267 }
268 else
269 {
270 nid.uFlags |= NIF_STATE;
271 nid.dwState = NIS_HIDDEN;
272 nid.dwStateMask = NIS_HIDDEN;
273
274 }
275 NcFreeNetconProperties(pProperties);
276 }
277
278 Shell_NotifyIconW(NIM_MODIFY, &nid);
279
280 if (nid.uFlags & NIF_ICON)
281 DestroyIcon(nid.hIcon);
282
283 pContext->dwInOctets = IfEntry.dwInOctets;
284 pContext->dwOutOctets = IfEntry.dwOutOctets;
285
286 if (hwndDlg)
287 UpdateLanStatusUiDlg(hwndDlg, &IfEntry, pContext);
288 }
289
290
291 VOID
292 InitializeLANStatusUiDlg(HWND hwndDlg, LANSTATUSUI_CONTEXT * pContext)
293 {
294 WCHAR szBuffer[MAX_PATH] = {0};
295 NETCON_PROPERTIES * pProperties;
296
297 if (pContext->pNet->GetProperties(&pProperties) != S_OK)
298 return;
299
300 if (pProperties->Status == NCS_DISCONNECTED)
301 LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, szBuffer, MAX_PATH);
302 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED)
303 LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, szBuffer, MAX_PATH);
304 else if (pProperties->Status == NCS_CONNECTING)
305 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, szBuffer, MAX_PATH);
306 else if (pProperties->Status == NCS_CONNECTED)
307 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, szBuffer, MAX_PATH);
308
309 SendDlgItemMessageW(hwndDlg, IDC_STATUS, WM_SETTEXT, 0, (LPARAM)szBuffer);
310
311 pContext->dwInOctets = 0;
312 pContext->dwOutOctets = 0;
313
314 /* update adapter info */
315 pContext->Status = -1;
316 UpdateLanStatus(hwndDlg, pContext);
317 NcFreeNetconProperties(pProperties);
318 }
319
320 static
321 VOID
322 InsertColumnToListView(
323 HWND hDlgCtrl,
324 UINT ResId,
325 UINT SubItem,
326 UINT Size)
327 {
328 WCHAR szBuffer[200];
329 LVCOLUMNW lc;
330
331 if (!LoadStringW(netshell_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
332 return;
333
334 memset(&lc, 0, sizeof(LV_COLUMN) );
335 lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
336 lc.iSubItem = SubItem;
337 lc.fmt = LVCFMT_FIXED_WIDTH;
338 lc.cx = Size;
339 lc.cchTextMax = wcslen(szBuffer);
340 lc.pszText = szBuffer;
341
342 (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, SubItem, (LPARAM)&lc);
343 }
344
345 static
346 VOID
347 AddIPAddressToListView(
348 HWND hDlgCtrl,
349 PIP_ADDR_STRING pAddr,
350 INT Index)
351 {
352 LVITEMW li;
353 PIP_ADDR_STRING pCur;
354 WCHAR szBuffer[100];
355 UINT SubIndex;
356
357 ZeroMemory(&li, sizeof(LVITEMW));
358 li.mask = LVIF_TEXT;
359 li.iItem = Index;
360 pCur = pAddr;
361 SubIndex = 0;
362
363 do
364 {
365 if (SubIndex)
366 {
367 ZeroMemory(&li, sizeof(LVITEMW));
368 li.mask = LVIF_TEXT;
369 li.iItem = Index;
370 li.iSubItem = 0;
371 li.pszText = (LPWSTR)L"";
372 li.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
373 }
374
375 if (MultiByteToWideChar(CP_ACP, 0, pCur->IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
376 {
377 li.pszText = szBuffer;
378 li.iSubItem = 1;
379 li.iItem = Index++;
380 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
381 }
382 SubIndex++;
383 pCur = pCur->Next;
384 }while(pCur && pCur->IpAddress.String[0]);
385 }
386
387 static
388 INT
389 InsertItemToListView(
390 HWND hDlgCtrl,
391 UINT ResId)
392 {
393 LVITEMW li;
394 WCHAR szBuffer[100];
395
396 ZeroMemory(&li, sizeof(LVITEMW));
397 li.mask = LVIF_TEXT;
398 li.iItem = ListView_GetItemCount(hDlgCtrl);
399 if (LoadStringW(netshell_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
400 {
401 li.pszText = szBuffer;
402 return (INT)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
403 }
404 return -1;
405 }
406
407
408 INT_PTR
409 CALLBACK
410 LANStatusUiDetailsDlg(
411 HWND hwndDlg,
412 UINT uMsg,
413 WPARAM wParam,
414 LPARAM lParam
415 )
416 {
417 LANSTATUSUI_CONTEXT * pContext;
418 LVITEMW li;
419 WCHAR szBuffer[100];
420 PIP_ADAPTER_INFO pAdapterInfo, pCurAdapter;
421 PIP_PER_ADAPTER_INFO pPerAdapter;
422 DWORD dwSize;
423 HWND hDlgCtrl;
424 RECT rect;
425
426 switch(uMsg)
427 {
428 case WM_INITDIALOG:
429 pContext = (LANSTATUSUI_CONTEXT*)lParam;
430
431 hDlgCtrl = GetDlgItem(hwndDlg, IDC_DETAILS);
432
433 /* get client rect */
434 GetClientRect(hDlgCtrl, &rect);
435
436 /* calculate column width */
437 dwSize = rect.right / 2;
438
439 InsertColumnToListView(hDlgCtrl, IDS_PROPERTY, 0, dwSize);
440 InsertColumnToListView(hDlgCtrl, IDS_VALUE, 1, dwSize);
441
442 dwSize = 0;
443 pCurAdapter = NULL;
444 pAdapterInfo = NULL;
445 if (GetAdaptersInfo(NULL, &dwSize) == ERROR_BUFFER_OVERFLOW)
446 {
447 pAdapterInfo = (PIP_ADAPTER_INFO)CoTaskMemAlloc(dwSize);
448 if (pAdapterInfo)
449 {
450 if (GetAdaptersInfo(pAdapterInfo, &dwSize) == NO_ERROR)
451 {
452 pCurAdapter = pAdapterInfo;
453 while(pCurAdapter && pCurAdapter->Index != pContext->dwAdapterIndex)
454 pCurAdapter = pCurAdapter->Next;
455
456 if(pCurAdapter->Index != pContext->dwAdapterIndex)
457 pCurAdapter = NULL;
458 }
459 }
460 }
461
462 ZeroMemory(&li, sizeof(LVITEMW));
463 li.mask = LVIF_TEXT;
464 li.iSubItem = 1;
465 li.pszText = szBuffer;
466
467 if (pCurAdapter)
468 {
469 li.iItem = InsertItemToListView(hDlgCtrl, IDS_PHYSICAL_ADDRESS);
470 if (li.iItem >= 0)
471 {
472 swprintf(szBuffer, L"%02x-%02x-%02x-%02x-%02x-%02x",pCurAdapter->Address[0], pCurAdapter->Address[1],
473 pCurAdapter->Address[2], pCurAdapter->Address[3], pCurAdapter->Address[4], pCurAdapter->Address[5]);
474 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
475 }
476 li.iItem = InsertItemToListView(hDlgCtrl, IDS_IP_ADDRESS);
477 if (li.iItem >= 0)
478 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
479 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
480
481 li.iItem = InsertItemToListView(hDlgCtrl, IDS_SUBNET_MASK);
482 if (li.iItem >= 0)
483 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpMask.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
484 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
485
486 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DEF_GATEWAY);
487 if (li.iItem >= 0 && pCurAdapter->GatewayList.IpAddress.String[0] != '0')
488 {
489 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->GatewayList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
490 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
491 }
492 #if 0
493 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_OBTAINED);
494 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_EXPIRES);
495 #endif
496 }
497
498 dwSize = 0;
499 if (GetPerAdapterInfo(pContext->dwAdapterIndex, NULL, &dwSize) == ERROR_BUFFER_OVERFLOW)
500 {
501 pPerAdapter = (PIP_PER_ADAPTER_INFO)CoTaskMemAlloc(dwSize);
502 if (pPerAdapter)
503 {
504 if (GetPerAdapterInfo(pContext->dwAdapterIndex, pPerAdapter, &dwSize) == ERROR_SUCCESS)
505 {
506 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DNS_SERVERS);
507 if (li.iItem >= 0)
508 AddIPAddressToListView(hDlgCtrl, &pPerAdapter->DnsServerList, li.iItem);
509 }
510 CoTaskMemFree(pPerAdapter);
511 }
512 }
513 #if 0
514 if (pCurAdapter)
515 {
516 li.iItem = InsertItemToListView(hDlgCtrl, IDS_WINS_SERVERS);
517 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->PrimaryWinsServer, li.iItem);
518 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->SecondaryWinsServer, li.iItem+1);
519 }
520 #endif
521 CoTaskMemFree(pAdapterInfo);
522 break;
523 case WM_COMMAND:
524 if (LOWORD(wParam) == IDC_CLOSE)
525 {
526 EndDialog(hwndDlg, FALSE);
527 break;
528 }
529 }
530 return FALSE;
531 }
532
533 INT_PTR
534 CALLBACK
535 LANStatusUiAdvancedDlg(
536 HWND hwndDlg,
537 UINT uMsg,
538 WPARAM wParam,
539 LPARAM lParam
540 )
541 {
542 WCHAR szBuffer[100] = {0};
543 PROPSHEETPAGE *page;
544 LANSTATUSUI_CONTEXT * pContext;
545 DWORD dwIpAddr;
546
547
548 switch(uMsg)
549 {
550 case WM_INITDIALOG:
551 page = (PROPSHEETPAGE*)lParam;
552 pContext = (LANSTATUSUI_CONTEXT*)page->lParam;
553 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
554 if (pContext->DHCPEnabled)
555 LoadStringW(netshell_hInstance, IDS_ASSIGNED_DHCP, szBuffer, sizeof(szBuffer)/sizeof(WCHAR));
556 else
557 LoadStringW(netshell_hInstance, IDS_ASSIGNED_MANUAL, szBuffer, sizeof(szBuffer)/sizeof(WCHAR));
558
559 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
560 SendDlgItemMessageW(hwndDlg, IDC_DETAILSTYPE, WM_SETTEXT, 0, (LPARAM)szBuffer);
561
562
563 dwIpAddr = ntohl(pContext->IpAddress);
564 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr),
565 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
566 SendDlgItemMessageW(hwndDlg, IDC_DETAILSIP, WM_SETTEXT, 0, (LPARAM)szBuffer);
567
568 dwIpAddr = ntohl(pContext->SubnetMask);
569 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr),
570 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
571 SendDlgItemMessageW(hwndDlg, IDC_DETAILSSUBNET, WM_SETTEXT, 0, (LPARAM)szBuffer);
572
573 dwIpAddr = ntohl(pContext->Gateway);
574 if (dwIpAddr)
575 {
576 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr),
577 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
578 SendDlgItemMessageW(hwndDlg, IDC_DETAILSGATEWAY, WM_SETTEXT, 0, (LPARAM)szBuffer);
579 }
580 return TRUE;
581 case WM_COMMAND:
582 if (LOWORD(wParam) == IDC_DETAILS)
583 {
584 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
585 if (pContext)
586 {
587 DialogBoxParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_LAN_NETSTATUSDETAILS), GetParent(hwndDlg),
588 LANStatusUiDetailsDlg, (LPARAM)pContext);
589 }
590 }
591 break;
592 default:
593 break;
594 }
595 return FALSE;
596 }
597
598 BOOL
599 FindNetworkAdapter(HDEVINFO hInfo, SP_DEVINFO_DATA *pDevInfo, LPWSTR pGuid)
600 {
601 DWORD dwIndex, dwSize;
602 HKEY hSubKey;
603 WCHAR szNetCfg[50];
604 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
605
606 dwIndex = 0;
607 do
608 {
609
610 ZeroMemory(pDevInfo, sizeof(SP_DEVINFO_DATA));
611 pDevInfo->cbSize = sizeof(SP_DEVINFO_DATA);
612
613 /* get device info */
614 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, pDevInfo))
615 break;
616
617 /* get device software registry path */
618 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, pDevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
619 break;
620
621 /* open device registry key */
622 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
623 break;
624
625 /* query NetCfgInstanceId for current device */
626 dwSize = sizeof(szNetCfg);
627 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
628 {
629 RegCloseKey(hSubKey);
630 break;
631 }
632 RegCloseKey(hSubKey);
633 if (!_wcsicmp(pGuid, szNetCfg))
634 {
635 return TRUE;
636 }
637 }
638 while(TRUE);
639
640 return FALSE;
641 }
642
643 VOID
644 DisableNetworkAdapter(INetConnection * pNet, LANSTATUSUI_CONTEXT * pContext, HWND hwndDlg)
645 {
646 HKEY hKey;
647 NETCON_PROPERTIES * pProperties;
648 LPOLESTR pDisplayName;
649 WCHAR szPath[200];
650 DWORD dwSize, dwType;
651 LPWSTR pPnp;
652 HDEVINFO hInfo;
653 SP_DEVINFO_DATA DevInfo;
654 SP_PROPCHANGE_PARAMS PropChangeParams;
655 BOOL bClose = FALSE;
656 NOTIFYICONDATAW nid;
657
658 if (FAILED(pNet->GetProperties(&pProperties)))
659 return;
660
661
662 hInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
663 if (!hInfo)
664 {
665 NcFreeNetconProperties(pProperties);
666 return;
667 }
668
669 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pDisplayName)))
670 {
671 NcFreeNetconProperties(pProperties);
672 SetupDiDestroyDeviceInfoList(hInfo);
673 return;
674 }
675 NcFreeNetconProperties(pProperties);
676
677 if (FindNetworkAdapter(hInfo, &DevInfo, pDisplayName))
678 {
679 PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
680 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; //;
681 PropChangeParams.StateChange = DICS_DISABLE;
682 PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
683 PropChangeParams.HwProfile = 0;
684
685 if (SetupDiSetClassInstallParams(hInfo, &DevInfo, &PropChangeParams.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS)))
686 {
687 if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hInfo, &DevInfo))
688 bClose = TRUE;
689 }
690 }
691 SetupDiDestroyDeviceInfoList(hInfo);
692
693 swprintf(szPath, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pDisplayName);
694 CoTaskMemFree(pDisplayName);
695
696 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
697 return;
698
699 dwSize = 0;
700 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_SZ)
701 {
702 RegCloseKey(hKey);
703 return;
704 }
705
706 pPnp = (LPWSTR)CoTaskMemAlloc(dwSize);
707 if (!pPnp)
708 {
709 RegCloseKey(hKey);
710 return;
711 }
712
713 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, (LPBYTE)pPnp, &dwSize) != ERROR_SUCCESS)
714 {
715 CoTaskMemFree(pPnp);
716 RegCloseKey(hKey);
717 return;
718 }
719 RegCloseKey(hKey);
720
721 swprintf(szPath, L"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Enum\\%s", pPnp);
722 CoTaskMemFree(pPnp);
723
724 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
725 return;
726
727 dwSize = 1; /* enable = 0, disable = 1 */
728 RegSetValueExW(hKey, L"CSConfigFlags", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD));
729 RegCloseKey(hKey);
730
731 if (!bClose)
732 return;
733
734 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_CANCEL);
735 ZeroMemory(&nid, sizeof(nid));
736 nid.cbSize = sizeof(nid);
737 nid.uID = pContext->uID;
738 nid.hWnd = pContext->hwndDlg;
739 nid.uFlags = NIF_STATE;
740 nid.dwState = NIS_HIDDEN;
741 nid.dwStateMask = NIS_HIDDEN;
742
743 Shell_NotifyIconW(NIM_MODIFY, &nid);
744 }
745
746
747 INT_PTR
748 CALLBACK
749 LANStatusUiDlg(
750 HWND hwndDlg,
751 UINT uMsg,
752 WPARAM wParam,
753 LPARAM lParam)
754 {
755 PROPSHEETPAGE *page;
756 LANSTATUSUI_CONTEXT * pContext;
757 LPPSHNOTIFY lppsn;
758
759 switch(uMsg)
760 {
761 case WM_INITDIALOG:
762 page = (PROPSHEETPAGE*)lParam;
763 pContext = (LANSTATUSUI_CONTEXT*)page->lParam;
764 pContext->hwndDlg = hwndDlg;
765 InitializeLANStatusUiDlg(hwndDlg, pContext);
766 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
767 return TRUE;
768 case WM_COMMAND:
769 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
770 if (LOWORD(wParam) == IDC_STATUS_PROPERTIES)
771 {
772 if (pContext)
773 {
774 ShowNetConnectionProperties(pContext->pNet, GetParent(pContext->hwndDlg));
775 BringWindowToTop(GetParent(pContext->hwndDlg));
776 }
777 break;
778 }
779 else if (LOWORD(wParam) == IDC_ENDISABLE)
780 {
781 DisableNetworkAdapter(pContext->pNet, pContext, hwndDlg);
782 break;
783 }
784 case WM_NOTIFY:
785 lppsn = (LPPSHNOTIFY) lParam;
786 if (lppsn->hdr.code == PSN_APPLY || lppsn->hdr.code == PSN_RESET)
787 {
788 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
789 SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
790 pContext->hwndDlg = NULL;
791 return TRUE;
792 }
793 break;
794 }
795 return FALSE;
796 }
797
798 VOID
799 InitializePropertyDialog(
800 LANSTATUSUI_CONTEXT * pContext,
801 NETCON_PROPERTIES * pProperties)
802 {
803 DWORD dwSize, dwAdapterIndex, dwResult;
804 LPOLESTR pStr;
805 IP_ADAPTER_INFO *pAdapterInfo, *pCurAdapter;
806
807 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pStr)))
808 {
809 return;
810 }
811
812 /* get the IfTable */
813 dwSize = 0;
814 dwResult = GetAdaptersInfo(NULL, &dwSize);
815 if (dwResult!= ERROR_BUFFER_OVERFLOW)
816 {
817 CoTaskMemFree(pStr);
818 return;
819 }
820
821 pAdapterInfo = (PIP_ADAPTER_INFO)CoTaskMemAlloc(dwSize);
822 if (!pAdapterInfo)
823 {
824 CoTaskMemFree(pAdapterInfo);
825 CoTaskMemFree(pStr);
826 return;
827 }
828
829 if (GetAdaptersInfo(pAdapterInfo, &dwSize) != NO_ERROR)
830 {
831 CoTaskMemFree(pAdapterInfo);
832 CoTaskMemFree(pStr);
833 return;
834 }
835
836 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, pStr, &dwAdapterIndex))
837 {
838 CoTaskMemFree(pAdapterInfo);
839 CoTaskMemFree(pStr);
840 return;
841 }
842
843 pCurAdapter = pAdapterInfo;
844 while(pCurAdapter->Index != dwAdapterIndex)
845 pCurAdapter = pCurAdapter->Next;
846
847
848 pContext->IpAddress = inet_addr(pCurAdapter->IpAddressList.IpAddress.String);
849 pContext->SubnetMask = inet_addr(pCurAdapter->IpAddressList.IpMask.String);
850 pContext->Gateway = inet_addr(pCurAdapter->GatewayList.IpAddress.String);
851 pContext->DHCPEnabled = pCurAdapter->DhcpEnabled;
852 CoTaskMemFree(pStr);
853 CoTaskMemFree(pAdapterInfo);
854 pContext->dwAdapterIndex = dwAdapterIndex;
855 }
856
857 VOID
858 ShowStatusPropertyDialog(
859 LANSTATUSUI_CONTEXT *pContext,
860 HWND hwndDlg)
861 {
862 HPROPSHEETPAGE hppages[2];
863 PROPSHEETHEADERW pinfo;
864 NETCON_PROPERTIES * pProperties = NULL;
865
866 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
867 ZeroMemory(hppages, sizeof(hppages));
868 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
869 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW;
870 pinfo.phpage = hppages;
871 pinfo.hwndParent = hwndDlg;
872
873 if (pContext->pNet->GetProperties(&pProperties) == S_OK)
874 {
875 if (pProperties->pszwName)
876 {
877 pinfo.pszCaption = pProperties->pszwName;
878 pinfo.dwFlags |= PSH_PROPTITLE;
879 }
880 InitializePropertyDialog(pContext, pProperties);
881 if (pProperties->MediaType == NCM_LAN && pProperties->Status == NCS_CONNECTED)
882 {
883 hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUS), LANStatusUiDlg, (LPARAM)pContext, NULL);
884 if (hppages[0])
885 pinfo.nPages++;
886
887 hppages[pinfo.nPages] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUSADVANCED), LANStatusUiAdvancedDlg, (LPARAM)pContext, NULL);
888 if (hppages[pinfo.nPages])
889 pinfo.nPages++;
890
891 if (pinfo.nPages)
892 {
893 PropertySheetW(&pinfo);
894 }
895 }
896 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED ||
897 pProperties->Status == NCS_HARDWARE_DISABLED)
898 {
899 ShowNetConnectionProperties(pContext->pNet, pContext->hwndDlg);
900 }
901
902 NcFreeNetconProperties(pProperties);
903 }
904 }
905
906 INT_PTR
907 CALLBACK
908 LANStatusDlg(
909 HWND hwndDlg,
910 UINT uMsg,
911 WPARAM wParam,
912 LPARAM lParam)
913 {
914 LANSTATUSUI_CONTEXT * pContext;
915
916 switch(uMsg)
917 {
918 case WM_INITDIALOG:
919 pContext = (LANSTATUSUI_CONTEXT *)lParam;
920 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
921 pContext->nIDEvent = SetTimer(hwndDlg, 0xFABC, 1000, NULL);
922 return TRUE;
923 case WM_TIMER:
924 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
925 if (wParam == (WPARAM)pContext->nIDEvent)
926 {
927 UpdateLanStatus(pContext->hwndDlg, pContext);
928 }
929 break;
930 case WM_SHOWSTATUSDLG:
931 if (LOWORD(lParam) == WM_LBUTTONDOWN)
932 {
933 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
934 if (!pContext)
935 break;
936
937 if (pContext->hwndDlg)
938 {
939 ShowWindow(GetParent(pContext->hwndDlg), SW_SHOW);
940 BringWindowToTop(GetParent(pContext->hwndDlg));
941 }
942 else
943 {
944 ShowStatusPropertyDialog(pContext, hwndDlg);
945 }
946 break;
947 }
948 break;
949 }
950 return FALSE;
951 }
952
953 HRESULT
954 CLanStatus::InitializeNetTaskbarNotifications()
955 {
956 NOTIFYICONDATAW nid;
957 HWND hwndDlg;
958 INetConnectionManager *pNetConMan;
959 IEnumNetConnection *pEnumCon;
960 INetConnection *pNetCon;
961 NETCON_PROPERTIES* pProps;
962 HRESULT hr;
963 ULONG Count;
964 ULONG Index;
965 NOTIFICATION_ITEM * pItem, *pLast = NULL;
966 LANSTATUSUI_CONTEXT * pContext;
967
968 TRACE("InitializeNetTaskbarNotifications\n");
969
970 if (pHead)
971 {
972 pItem = pHead;
973 while(pItem)
974 {
975 hr = pItem->pNet->GetProperties(&pProps);
976 if (SUCCEEDED(hr))
977 {
978 ZeroMemory(&nid, sizeof(nid));
979 nid.cbSize = sizeof(nid);
980 nid.uID = pItem->uID;
981 nid.hWnd = pItem->hwndDlg;
982 nid.uFlags = NIF_STATE;
983 if (pProps->dwCharacter & NCCF_SHOW_ICON)
984 nid.dwState = 0;
985 else
986 nid.dwState = NIS_HIDDEN;
987
988 nid.dwStateMask = NIS_HIDDEN;
989 Shell_NotifyIconW(NIM_MODIFY, &nid);
990 NcFreeNetconProperties(pProps);
991 }
992 pItem = pItem->pNext;
993 }
994 return S_OK;
995 }
996 /* get an instance to of IConnectionManager */
997
998 //hr = CoCreateInstance(&CLSID_ConnectionManager, NULL, CLSCTX_INPROC_SERVER, &IID_INetConnectionManager, (LPVOID*)&pNetConMan);
999
1000 hr = INetConnectionManager_Constructor(NULL, IID_INetConnectionManager, (LPVOID*)&pNetConMan);
1001 if (FAILED(hr))
1002 {
1003 ERR("INetConnectionManager_Constructor failed\n");
1004 return hr;
1005 }
1006
1007 hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon);
1008 if (FAILED(hr))
1009 {
1010 ERR("EnumConnections failed\n");
1011 pNetConMan->Release();
1012 return hr;
1013 }
1014
1015 Index = 1;
1016 do
1017 {
1018 hr = pEnumCon->Next(1, &pNetCon, &Count);
1019 if (hr == S_OK)
1020 {
1021 TRACE("new connection\n");
1022 pItem = (NOTIFICATION_ITEM*)CoTaskMemAlloc(sizeof(NOTIFICATION_ITEM));
1023 if (!pItem)
1024 break;
1025
1026 pContext = (LANSTATUSUI_CONTEXT*)CoTaskMemAlloc(sizeof(LANSTATUSUI_CONTEXT));
1027 if (!pContext)
1028 {
1029 CoTaskMemFree(pItem);
1030 break;
1031 }
1032
1033 ZeroMemory(pContext, sizeof(LANSTATUSUI_CONTEXT));
1034 pContext->uID = Index;
1035 pContext->pNet = pNetCon;
1036 pItem->uID = Index;
1037 pItem->pNext = NULL;
1038 pItem->pNet = pNetCon;
1039 hwndDlg = CreateDialogParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_STATUS), NULL, LANStatusDlg, (LPARAM)pContext);
1040 if (hwndDlg)
1041 {
1042 ZeroMemory(&nid, sizeof(nid));
1043 nid.cbSize = sizeof(nid);
1044 nid.uID = Index++;
1045 nid.uFlags = NIF_MESSAGE;
1046 nid.uVersion = 3;
1047 nid.uCallbackMessage = WM_SHOWSTATUSDLG;
1048 nid.hWnd = hwndDlg;
1049
1050 hr = pNetCon->GetProperties(&pProps);
1051 if (SUCCEEDED(hr))
1052 {
1053 CopyMemory(&pItem->guidItem, &pProps->guidId, sizeof(GUID));
1054 if (!(pProps->dwCharacter & NCCF_SHOW_ICON))
1055 {
1056 nid.dwState = NIS_HIDDEN;
1057 nid.dwStateMask = NIS_HIDDEN;
1058 nid.uFlags |= NIF_STATE;
1059 }
1060 if (pProps->Status == NCS_MEDIA_DISCONNECTED || pProps->Status == NCS_DISCONNECTED || pProps->Status == NCS_HARDWARE_DISABLED)
1061 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF));
1062 else if (pProps->Status == NCS_CONNECTED)
1063 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE));
1064
1065 if (nid.hIcon)
1066 nid.uFlags |= NIF_ICON;
1067
1068 wcscpy(nid.szTip, pProps->pszwName);
1069 nid.uFlags |= NIF_TIP;
1070 }
1071 pContext->hwndStatusDlg = hwndDlg;
1072 pItem->hwndDlg = hwndDlg;
1073
1074 if (Shell_NotifyIconW(NIM_ADD, &nid))
1075 {
1076 if (pLast)
1077 pLast->pNext = pItem;
1078 else
1079 pHead = pItem;
1080
1081 pLast = pItem;
1082 Index++;
1083 }
1084 else
1085 {
1086 ERR("Shell_NotifyIconW failed\n");
1087 CoTaskMemFree(pItem);
1088 }
1089
1090 if (nid.uFlags & NIF_ICON)
1091 DestroyIcon(nid.hIcon);
1092 } else
1093 ERR("CreateDialogParamW failed\n");
1094 }
1095 } while(hr == S_OK);
1096
1097 lpNetMan = pNetConMan;
1098 pEnumCon->Release();
1099 return S_OK;
1100 }
1101
1102 HRESULT
1103 CLanStatus::ShowStatusDialogByCLSID(const GUID *pguidCmdGroup)
1104 {
1105 NOTIFICATION_ITEM *pItem;
1106
1107 pItem = pHead;
1108 while(pItem)
1109 {
1110 if (IsEqualGUID(pItem->guidItem, *pguidCmdGroup))
1111 {
1112 SendMessageW(pItem->hwndDlg, WM_SHOWSTATUSDLG, 0, WM_LBUTTONDOWN);
1113 return S_OK;
1114 }
1115 pItem = pItem->pNext;
1116 }
1117
1118 ERR("not found\n");
1119 return E_FAIL;
1120 }
1121
1122 HRESULT
1123 WINAPI
1124 CLanStatus::QueryInterface(
1125 REFIID iid,
1126 LPVOID *ppvObj)
1127 {
1128 *ppvObj = NULL;
1129
1130 if (IsEqualIID(iid, IID_IUnknown) ||
1131 IsEqualIID(iid, IID_IOleCommandTarget))
1132 {
1133 *ppvObj = this;
1134 AddRef();
1135 return S_OK;
1136 }
1137 MessageBoxW(NULL, L"IOleCommandTarget_fnQueryInterface", NULL, MB_OK);
1138 return E_NOINTERFACE;
1139 }
1140
1141 ULONG
1142 WINAPI
1143 CLanStatus::AddRef()
1144 {
1145 ULONG refCount = InterlockedIncrement(&ref);
1146
1147 return refCount;
1148 }
1149
1150 ULONG
1151 WINAPI
1152 CLanStatus::Release()
1153 {
1154 #if 0 // WTF?!
1155 ULONG refCount = InterlockedDecrement(&ref);
1156
1157 if (!refCount)
1158 delete this;
1159
1160 return refCount;
1161 #else
1162 return 1;
1163 #endif
1164 }
1165
1166 HRESULT
1167 WINAPI
1168 CLanStatus::QueryStatus(
1169 const GUID *pguidCmdGroup,
1170 ULONG cCmds,
1171 OLECMD *prgCmds,
1172 OLECMDTEXT *pCmdText)
1173 {
1174 MessageBoxW(NULL, pCmdText->rgwz, L"IOleCommandTarget_fnQueryStatus", MB_OK);
1175 return E_NOTIMPL;
1176 }
1177
1178 HRESULT
1179 WINAPI
1180 CLanStatus::Exec(
1181 const GUID *pguidCmdGroup,
1182 DWORD nCmdID,
1183 DWORD nCmdexecopt,
1184 VARIANT *pvaIn,
1185 VARIANT *pvaOut)
1186 {
1187 if (pguidCmdGroup)
1188 {
1189 if (IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject))
1190 {
1191 return InitializeNetTaskbarNotifications();
1192 }
1193 else
1194 {
1195 /* invoke status dialog */
1196 return ShowStatusDialogByCLSID(pguidCmdGroup);
1197 }
1198 }
1199 return S_OK;
1200 }
1201
1202 HRESULT WINAPI LanConnectStatusUI_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv)
1203 {
1204 TRACE("LanConnectStatusUI_Constructor\n");
1205
1206 if (!ppv)
1207 return E_POINTER;
1208
1209 if (pUnkOuter)
1210 return CLASS_E_NOAGGREGATION;
1211
1212 CLanStatus *pLanStatus = new CLanStatus;
1213 if (!pLanStatus)
1214 return E_OUTOFMEMORY;
1215
1216 pLanStatus->AddRef();
1217 static volatile CLanStatus *pCachedLanStatus = NULL;
1218 if (InterlockedCompareExchangePointer((void **)&pCachedLanStatus, pLanStatus, NULL) != NULL)
1219 pLanStatus->Release();
1220
1221 return ((CLanStatus*)pCachedLanStatus)->QueryInterface(riid, ppv);
1222 }
1223