Sync with trunk r58033.
[reactos.git] / 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
425 switch(uMsg)
426 {
427 case WM_INITDIALOG:
428 pContext = (LANSTATUSUI_CONTEXT*)lParam;
429
430 hDlgCtrl = GetDlgItem(hwndDlg, IDC_DETAILS);
431 InsertColumnToListView(hDlgCtrl, IDS_PROPERTY, 0, 80);
432 InsertColumnToListView(hDlgCtrl, IDS_VALUE, 1, 80);
433
434 dwSize = 0;
435 pCurAdapter = NULL;
436 pAdapterInfo = NULL;
437 if (GetAdaptersInfo(NULL, &dwSize) == ERROR_BUFFER_OVERFLOW)
438 {
439 pAdapterInfo = (PIP_ADAPTER_INFO)CoTaskMemAlloc(dwSize);
440 if (pAdapterInfo)
441 {
442 if (GetAdaptersInfo(pAdapterInfo, &dwSize) == NO_ERROR)
443 {
444 pCurAdapter = pAdapterInfo;
445 while(pCurAdapter && pCurAdapter->Index != pContext->dwAdapterIndex)
446 pCurAdapter = pCurAdapter->Next;
447
448 if(pCurAdapter->Index != pContext->dwAdapterIndex)
449 pCurAdapter = NULL;
450 }
451 }
452 }
453
454 ZeroMemory(&li, sizeof(LVITEMW));
455 li.mask = LVIF_TEXT;
456 li.iSubItem = 1;
457 li.pszText = szBuffer;
458
459 if (pCurAdapter)
460 {
461 li.iItem = InsertItemToListView(hDlgCtrl, IDS_PHYSICAL_ADDRESS);
462 if (li.iItem >= 0)
463 {
464 swprintf(szBuffer, L"%02x-%02x-%02x-%02x-%02x-%02x",pCurAdapter->Address[0], pCurAdapter->Address[1],
465 pCurAdapter->Address[2], pCurAdapter->Address[3], pCurAdapter->Address[4], pCurAdapter->Address[5]);
466 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
467 }
468 li.iItem = InsertItemToListView(hDlgCtrl, IDS_IP_ADDRESS);
469 if (li.iItem >= 0)
470 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
471 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
472
473 li.iItem = InsertItemToListView(hDlgCtrl, IDS_SUBNET_MASK);
474 if (li.iItem >= 0)
475 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpMask.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
476 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
477
478 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DEF_GATEWAY);
479 if (li.iItem >= 0 && pCurAdapter->GatewayList.IpAddress.String[0] != '0')
480 {
481 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->GatewayList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
482 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
483 }
484 #if 0
485 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_OBTAINED);
486 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_EXPIRES);
487 #endif
488 }
489
490 dwSize = 0;
491 if (GetPerAdapterInfo(pContext->dwAdapterIndex, NULL, &dwSize) == ERROR_BUFFER_OVERFLOW)
492 {
493 pPerAdapter = (PIP_PER_ADAPTER_INFO)CoTaskMemAlloc(dwSize);
494 if (pPerAdapter)
495 {
496 if (GetPerAdapterInfo(pContext->dwAdapterIndex, pPerAdapter, &dwSize) == ERROR_SUCCESS)
497 {
498 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DNS_SERVERS);
499 if (li.iItem >= 0)
500 AddIPAddressToListView(hDlgCtrl, &pPerAdapter->DnsServerList, li.iItem);
501 }
502 CoTaskMemFree(pPerAdapter);
503 }
504 }
505 #if 0
506 if (pCurAdapter)
507 {
508 li.iItem = InsertItemToListView(hDlgCtrl, IDS_WINS_SERVERS);
509 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->PrimaryWinsServer, li.iItem);
510 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->SecondaryWinsServer, li.iItem+1);
511 }
512 #endif
513 CoTaskMemFree(pAdapterInfo);
514 break;
515 case WM_COMMAND:
516 if (LOWORD(wParam) == IDC_CLOSE)
517 {
518 EndDialog(hwndDlg, FALSE);
519 break;
520 }
521 }
522 return FALSE;
523 }
524
525 INT_PTR
526 CALLBACK
527 LANStatusUiAdvancedDlg(
528 HWND hwndDlg,
529 UINT uMsg,
530 WPARAM wParam,
531 LPARAM lParam
532 )
533 {
534 WCHAR szBuffer[100] = {0};
535 PROPSHEETPAGE *page;
536 LANSTATUSUI_CONTEXT * pContext;
537 DWORD dwIpAddr;
538
539
540 switch(uMsg)
541 {
542 case WM_INITDIALOG:
543 page = (PROPSHEETPAGE*)lParam;
544 pContext = (LANSTATUSUI_CONTEXT*)page->lParam;
545 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
546 if (pContext->DHCPEnabled)
547 LoadStringW(netshell_hInstance, IDS_ASSIGNED_DHCP, szBuffer, sizeof(szBuffer)/sizeof(WCHAR));
548 else
549 LoadStringW(netshell_hInstance, IDS_ASSIGNED_MANUAL, szBuffer, sizeof(szBuffer)/sizeof(WCHAR));
550
551 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
552 SendDlgItemMessageW(hwndDlg, IDC_DETAILSTYPE, WM_SETTEXT, 0, (LPARAM)szBuffer);
553
554
555 dwIpAddr = ntohl(pContext->IpAddress);
556 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr),
557 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
558 SendDlgItemMessageW(hwndDlg, IDC_DETAILSIP, WM_SETTEXT, 0, (LPARAM)szBuffer);
559
560 dwIpAddr = ntohl(pContext->SubnetMask);
561 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr),
562 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
563 SendDlgItemMessageW(hwndDlg, IDC_DETAILSSUBNET, WM_SETTEXT, 0, (LPARAM)szBuffer);
564
565 dwIpAddr = ntohl(pContext->Gateway);
566 if (dwIpAddr)
567 {
568 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr),
569 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
570 SendDlgItemMessageW(hwndDlg, IDC_DETAILSGATEWAY, WM_SETTEXT, 0, (LPARAM)szBuffer);
571 }
572 return TRUE;
573 case WM_COMMAND:
574 if (LOWORD(wParam) == IDC_DETAILS)
575 {
576 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
577 if (pContext)
578 {
579 DialogBoxParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_LAN_NETSTATUSDETAILS), GetParent(hwndDlg),
580 LANStatusUiDetailsDlg, (LPARAM)pContext);
581 }
582 }
583 break;
584 default:
585 break;
586 }
587 return FALSE;
588 }
589
590 BOOL
591 FindNetworkAdapter(HDEVINFO hInfo, SP_DEVINFO_DATA *pDevInfo, LPWSTR pGuid)
592 {
593 DWORD dwIndex, dwSize;
594 HKEY hSubKey;
595 WCHAR szNetCfg[50];
596 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
597
598 dwIndex = 0;
599 do
600 {
601
602 ZeroMemory(pDevInfo, sizeof(SP_DEVINFO_DATA));
603 pDevInfo->cbSize = sizeof(SP_DEVINFO_DATA);
604
605 /* get device info */
606 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, pDevInfo))
607 break;
608
609 /* get device software registry path */
610 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, pDevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
611 break;
612
613 /* open device registry key */
614 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
615 break;
616
617 /* query NetCfgInstanceId for current device */
618 dwSize = sizeof(szNetCfg);
619 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
620 {
621 RegCloseKey(hSubKey);
622 break;
623 }
624 RegCloseKey(hSubKey);
625 if (!_wcsicmp(pGuid, szNetCfg))
626 {
627 return TRUE;
628 }
629 }
630 while(TRUE);
631
632 return FALSE;
633 }
634
635 VOID
636 DisableNetworkAdapter(INetConnection * pNet, LANSTATUSUI_CONTEXT * pContext, HWND hwndDlg)
637 {
638 HKEY hKey;
639 NETCON_PROPERTIES * pProperties;
640 LPOLESTR pDisplayName;
641 WCHAR szPath[200];
642 DWORD dwSize, dwType;
643 LPWSTR pPnp;
644 HDEVINFO hInfo;
645 SP_DEVINFO_DATA DevInfo;
646 SP_PROPCHANGE_PARAMS PropChangeParams;
647 BOOL bClose = FALSE;
648 NOTIFYICONDATAW nid;
649
650 if (FAILED(pNet->GetProperties(&pProperties)))
651 return;
652
653
654 hInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
655 if (!hInfo)
656 {
657 NcFreeNetconProperties(pProperties);
658 return;
659 }
660
661 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pDisplayName)))
662 {
663 NcFreeNetconProperties(pProperties);
664 SetupDiDestroyDeviceInfoList(hInfo);
665 return;
666 }
667 NcFreeNetconProperties(pProperties);
668
669 if (FindNetworkAdapter(hInfo, &DevInfo, pDisplayName))
670 {
671 PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
672 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; //;
673 PropChangeParams.StateChange = DICS_DISABLE;
674 PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
675 PropChangeParams.HwProfile = 0;
676
677 if (SetupDiSetClassInstallParams(hInfo, &DevInfo, &PropChangeParams.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS)))
678 {
679 if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hInfo, &DevInfo))
680 bClose = TRUE;
681 }
682 }
683 SetupDiDestroyDeviceInfoList(hInfo);
684
685 swprintf(szPath, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pDisplayName);
686 CoTaskMemFree(pDisplayName);
687
688 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
689 return;
690
691 dwSize = 0;
692 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_SZ)
693 {
694 RegCloseKey(hKey);
695 return;
696 }
697
698 pPnp = (LPWSTR)CoTaskMemAlloc(dwSize);
699 if (!pPnp)
700 {
701 RegCloseKey(hKey);
702 return;
703 }
704
705 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, (LPBYTE)pPnp, &dwSize) != ERROR_SUCCESS)
706 {
707 CoTaskMemFree(pPnp);
708 RegCloseKey(hKey);
709 return;
710 }
711 RegCloseKey(hKey);
712
713 swprintf(szPath, L"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Enum\\%s", pPnp);
714 CoTaskMemFree(pPnp);
715
716 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
717 return;
718
719 dwSize = 1; /* enable = 0, disable = 1 */
720 RegSetValueExW(hKey, L"CSConfigFlags", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD));
721 RegCloseKey(hKey);
722
723 if (!bClose)
724 return;
725
726 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_CANCEL);
727 ZeroMemory(&nid, sizeof(nid));
728 nid.cbSize = sizeof(nid);
729 nid.uID = pContext->uID;
730 nid.hWnd = pContext->hwndDlg;
731 nid.uFlags = NIF_STATE;
732 nid.dwState = NIS_HIDDEN;
733 nid.dwStateMask = NIS_HIDDEN;
734
735 Shell_NotifyIconW(NIM_MODIFY, &nid);
736 }
737
738
739 INT_PTR
740 CALLBACK
741 LANStatusUiDlg(
742 HWND hwndDlg,
743 UINT uMsg,
744 WPARAM wParam,
745 LPARAM lParam)
746 {
747 PROPSHEETPAGE *page;
748 LANSTATUSUI_CONTEXT * pContext;
749 LPPSHNOTIFY lppsn;
750
751 switch(uMsg)
752 {
753 case WM_INITDIALOG:
754 page = (PROPSHEETPAGE*)lParam;
755 pContext = (LANSTATUSUI_CONTEXT*)page->lParam;
756 pContext->hwndDlg = hwndDlg;
757 InitializeLANStatusUiDlg(hwndDlg, pContext);
758 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
759 return TRUE;
760 case WM_COMMAND:
761 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
762 if (LOWORD(wParam) == IDC_STATUS_PROPERTIES)
763 {
764 if (pContext)
765 {
766 ShowNetConnectionProperties(pContext->pNet, GetParent(pContext->hwndDlg));
767 BringWindowToTop(GetParent(pContext->hwndDlg));
768 }
769 break;
770 }
771 else if (LOWORD(wParam) == IDC_ENDISABLE)
772 {
773 DisableNetworkAdapter(pContext->pNet, pContext, hwndDlg);
774 break;
775 }
776 case WM_NOTIFY:
777 lppsn = (LPPSHNOTIFY) lParam;
778 if (lppsn->hdr.code == PSN_APPLY || lppsn->hdr.code == PSN_RESET)
779 {
780 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
781 SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR);
782 pContext->hwndDlg = NULL;
783 return TRUE;
784 }
785 break;
786 }
787 return FALSE;
788 }
789
790 VOID
791 InitializePropertyDialog(
792 LANSTATUSUI_CONTEXT * pContext,
793 NETCON_PROPERTIES * pProperties)
794 {
795 DWORD dwSize, dwAdapterIndex, dwResult;
796 LPOLESTR pStr;
797 IP_ADAPTER_INFO *pAdapterInfo, *pCurAdapter;
798
799 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pStr)))
800 {
801 return;
802 }
803
804 /* get the IfTable */
805 dwSize = 0;
806 dwResult = GetAdaptersInfo(NULL, &dwSize);
807 if (dwResult!= ERROR_BUFFER_OVERFLOW)
808 {
809 CoTaskMemFree(pStr);
810 return;
811 }
812
813 pAdapterInfo = (PIP_ADAPTER_INFO)CoTaskMemAlloc(dwSize);
814 if (!pAdapterInfo)
815 {
816 CoTaskMemFree(pAdapterInfo);
817 CoTaskMemFree(pStr);
818 return;
819 }
820
821 if (GetAdaptersInfo(pAdapterInfo, &dwSize) != NO_ERROR)
822 {
823 CoTaskMemFree(pAdapterInfo);
824 CoTaskMemFree(pStr);
825 return;
826 }
827
828 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, pStr, &dwAdapterIndex))
829 {
830 CoTaskMemFree(pAdapterInfo);
831 CoTaskMemFree(pStr);
832 return;
833 }
834
835 pCurAdapter = pAdapterInfo;
836 while(pCurAdapter->Index != dwAdapterIndex)
837 pCurAdapter = pCurAdapter->Next;
838
839
840 pContext->IpAddress = inet_addr(pCurAdapter->IpAddressList.IpAddress.String);
841 pContext->SubnetMask = inet_addr(pCurAdapter->IpAddressList.IpMask.String);
842 pContext->Gateway = inet_addr(pCurAdapter->GatewayList.IpAddress.String);
843 pContext->DHCPEnabled = pCurAdapter->DhcpEnabled;
844 CoTaskMemFree(pStr);
845 CoTaskMemFree(pAdapterInfo);
846 pContext->dwAdapterIndex = dwAdapterIndex;
847 }
848
849 VOID
850 ShowStatusPropertyDialog(
851 LANSTATUSUI_CONTEXT *pContext,
852 HWND hwndDlg)
853 {
854 HPROPSHEETPAGE hppages[2];
855 PROPSHEETHEADERW pinfo;
856 NETCON_PROPERTIES * pProperties = NULL;
857
858 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
859 ZeroMemory(hppages, sizeof(hppages));
860 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
861 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW;
862 pinfo.phpage = hppages;
863 pinfo.hwndParent = hwndDlg;
864
865 if (pContext->pNet->GetProperties(&pProperties) == S_OK)
866 {
867 if (pProperties->pszwName)
868 {
869 pinfo.pszCaption = pProperties->pszwName;
870 pinfo.dwFlags |= PSH_PROPTITLE;
871 }
872 InitializePropertyDialog(pContext, pProperties);
873 if (pProperties->MediaType == NCM_LAN && pProperties->Status == NCS_CONNECTED)
874 {
875 hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUS), LANStatusUiDlg, (LPARAM)pContext, NULL);
876 if (hppages[0])
877 pinfo.nPages++;
878
879 hppages[pinfo.nPages] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUSADVANCED), LANStatusUiAdvancedDlg, (LPARAM)pContext, NULL);
880 if (hppages[pinfo.nPages])
881 pinfo.nPages++;
882
883 if (pinfo.nPages)
884 {
885 PropertySheetW(&pinfo);
886 }
887 }
888 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED ||
889 pProperties->Status == NCS_HARDWARE_DISABLED)
890 {
891 ShowNetConnectionProperties(pContext->pNet, pContext->hwndDlg);
892 }
893
894 NcFreeNetconProperties(pProperties);
895 }
896 }
897
898 INT_PTR
899 CALLBACK
900 LANStatusDlg(
901 HWND hwndDlg,
902 UINT uMsg,
903 WPARAM wParam,
904 LPARAM lParam)
905 {
906 LANSTATUSUI_CONTEXT * pContext;
907
908 switch(uMsg)
909 {
910 case WM_INITDIALOG:
911 pContext = (LANSTATUSUI_CONTEXT *)lParam;
912 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
913 pContext->nIDEvent = SetTimer(hwndDlg, 0xFABC, 1000, NULL);
914 return TRUE;
915 case WM_TIMER:
916 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
917 if (wParam == (WPARAM)pContext->nIDEvent)
918 {
919 UpdateLanStatus(pContext->hwndDlg, pContext);
920 }
921 break;
922 case WM_SHOWSTATUSDLG:
923 if (LOWORD(lParam) == WM_LBUTTONDOWN)
924 {
925 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER);
926 if (!pContext)
927 break;
928
929 if (pContext->hwndDlg)
930 {
931 ShowWindow(GetParent(pContext->hwndDlg), SW_SHOW);
932 BringWindowToTop(GetParent(pContext->hwndDlg));
933 }
934 else
935 {
936 ShowStatusPropertyDialog(pContext, hwndDlg);
937 }
938 break;
939 }
940 break;
941 }
942 return FALSE;
943 }
944
945 HRESULT
946 CLanStatus::InitializeNetTaskbarNotifications()
947 {
948 NOTIFYICONDATAW nid;
949 HWND hwndDlg;
950 INetConnectionManager *pNetConMan;
951 IEnumNetConnection *pEnumCon;
952 INetConnection *pNetCon;
953 NETCON_PROPERTIES* pProps;
954 HRESULT hr;
955 ULONG Count;
956 ULONG Index;
957 NOTIFICATION_ITEM * pItem, *pLast = NULL;
958 LANSTATUSUI_CONTEXT * pContext;
959
960 TRACE("InitializeNetTaskbarNotifications\n");
961
962 if (pHead)
963 {
964 pItem = pHead;
965 while(pItem)
966 {
967 hr = pItem->pNet->GetProperties(&pProps);
968 if (SUCCEEDED(hr))
969 {
970 ZeroMemory(&nid, sizeof(nid));
971 nid.cbSize = sizeof(nid);
972 nid.uID = pItem->uID;
973 nid.hWnd = pItem->hwndDlg;
974 nid.uFlags = NIF_STATE;
975 if (pProps->dwCharacter & NCCF_SHOW_ICON)
976 nid.dwState = 0;
977 else
978 nid.dwState = NIS_HIDDEN;
979
980 nid.dwStateMask = NIS_HIDDEN;
981 Shell_NotifyIconW(NIM_MODIFY, &nid);
982 NcFreeNetconProperties(pProps);
983 }
984 pItem = pItem->pNext;
985 }
986 return S_OK;
987 }
988 /* get an instance to of IConnectionManager */
989
990 //hr = CoCreateInstance(&CLSID_ConnectionManager, NULL, CLSCTX_INPROC_SERVER, &IID_INetConnectionManager, (LPVOID*)&pNetConMan);
991
992 hr = INetConnectionManager_Constructor(NULL, IID_INetConnectionManager, (LPVOID*)&pNetConMan);
993 if (FAILED(hr))
994 {
995 ERR("INetConnectionManager_Constructor failed\n");
996 return hr;
997 }
998
999 hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon);
1000 if (FAILED(hr))
1001 {
1002 ERR("EnumConnections failed\n");
1003 pNetConMan->Release();
1004 return hr;
1005 }
1006
1007 Index = 1;
1008 do
1009 {
1010 hr = pEnumCon->Next(1, &pNetCon, &Count);
1011 if (hr == S_OK)
1012 {
1013 TRACE("new connection\n");
1014 pItem = (NOTIFICATION_ITEM*)CoTaskMemAlloc(sizeof(NOTIFICATION_ITEM));
1015 if (!pItem)
1016 break;
1017
1018 pContext = (LANSTATUSUI_CONTEXT*)CoTaskMemAlloc(sizeof(LANSTATUSUI_CONTEXT));
1019 if (!pContext)
1020 {
1021 CoTaskMemFree(pItem);
1022 break;
1023 }
1024
1025 ZeroMemory(pContext, sizeof(LANSTATUSUI_CONTEXT));
1026 pContext->uID = Index;
1027 pContext->pNet = pNetCon;
1028 pItem->uID = Index;
1029 pItem->pNext = NULL;
1030 pItem->pNet = pNetCon;
1031 hwndDlg = CreateDialogParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_STATUS), NULL, LANStatusDlg, (LPARAM)pContext);
1032 if (hwndDlg)
1033 {
1034 ZeroMemory(&nid, sizeof(nid));
1035 nid.cbSize = sizeof(nid);
1036 nid.uID = Index++;
1037 nid.uFlags = NIF_MESSAGE;
1038 nid.uVersion = 3;
1039 nid.uCallbackMessage = WM_SHOWSTATUSDLG;
1040 nid.hWnd = hwndDlg;
1041
1042 hr = pNetCon->GetProperties(&pProps);
1043 if (SUCCEEDED(hr))
1044 {
1045 CopyMemory(&pItem->guidItem, &pProps->guidId, sizeof(GUID));
1046 if (!(pProps->dwCharacter & NCCF_SHOW_ICON))
1047 {
1048 nid.dwState = NIS_HIDDEN;
1049 nid.dwStateMask = NIS_HIDDEN;
1050 nid.uFlags |= NIF_STATE;
1051 }
1052 if (pProps->Status == NCS_MEDIA_DISCONNECTED || pProps->Status == NCS_DISCONNECTED || pProps->Status == NCS_HARDWARE_DISABLED)
1053 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF));
1054 else if (pProps->Status == NCS_CONNECTED)
1055 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE));
1056
1057 if (nid.hIcon)
1058 nid.uFlags |= NIF_ICON;
1059
1060 wcscpy(nid.szTip, pProps->pszwName);
1061 nid.uFlags |= NIF_TIP;
1062 }
1063 pContext->hwndStatusDlg = hwndDlg;
1064 pItem->hwndDlg = hwndDlg;
1065
1066 if (Shell_NotifyIconW(NIM_ADD, &nid))
1067 {
1068 if (pLast)
1069 pLast->pNext = pItem;
1070 else
1071 pHead = pItem;
1072
1073 pLast = pItem;
1074 Index++;
1075 }
1076 else
1077 {
1078 ERR("Shell_NotifyIconW failed\n");
1079 CoTaskMemFree(pItem);
1080 }
1081
1082 if (nid.uFlags & NIF_ICON)
1083 DestroyIcon(nid.hIcon);
1084 } else
1085 ERR("CreateDialogParamW failed\n");
1086 }
1087 } while(hr == S_OK);
1088
1089 lpNetMan = pNetConMan;
1090 pEnumCon->Release();
1091 return S_OK;
1092 }
1093
1094 HRESULT
1095 CLanStatus::ShowStatusDialogByCLSID(const GUID *pguidCmdGroup)
1096 {
1097 NOTIFICATION_ITEM *pItem;
1098
1099 pItem = pHead;
1100 while(pItem)
1101 {
1102 if (IsEqualGUID(pItem->guidItem, *pguidCmdGroup))
1103 {
1104 SendMessageW(pItem->hwndDlg, WM_SHOWSTATUSDLG, 0, WM_LBUTTONDOWN);
1105 return S_OK;
1106 }
1107 pItem = pItem->pNext;
1108 }
1109
1110 ERR("not found\n");
1111 return E_FAIL;
1112 }
1113
1114 HRESULT
1115 WINAPI
1116 CLanStatus::QueryInterface(
1117 REFIID iid,
1118 LPVOID *ppvObj)
1119 {
1120 *ppvObj = NULL;
1121
1122 if (IsEqualIID(iid, IID_IUnknown) ||
1123 IsEqualIID(iid, IID_IOleCommandTarget))
1124 {
1125 *ppvObj = this;
1126 AddRef();
1127 return S_OK;
1128 }
1129 MessageBoxW(NULL, L"IOleCommandTarget_fnQueryInterface", NULL, MB_OK);
1130 return E_NOINTERFACE;
1131 }
1132
1133 ULONG
1134 WINAPI
1135 CLanStatus::AddRef()
1136 {
1137 ULONG refCount = InterlockedIncrement(&ref);
1138
1139 return refCount;
1140 }
1141
1142 ULONG
1143 WINAPI
1144 CLanStatus::Release()
1145 {
1146 #if 0 // WTF?!
1147 ULONG refCount = InterlockedDecrement(&ref);
1148
1149 if (!refCount)
1150 delete this;
1151
1152 return refCount;
1153 #else
1154 return 1;
1155 #endif
1156 }
1157
1158 HRESULT
1159 WINAPI
1160 CLanStatus::QueryStatus(
1161 const GUID *pguidCmdGroup,
1162 ULONG cCmds,
1163 OLECMD *prgCmds,
1164 OLECMDTEXT *pCmdText)
1165 {
1166 MessageBoxW(NULL, pCmdText->rgwz, L"IOleCommandTarget_fnQueryStatus", MB_OK);
1167 return E_NOTIMPL;
1168 }
1169
1170 HRESULT
1171 WINAPI
1172 CLanStatus::Exec(
1173 const GUID *pguidCmdGroup,
1174 DWORD nCmdID,
1175 DWORD nCmdexecopt,
1176 VARIANT *pvaIn,
1177 VARIANT *pvaOut)
1178 {
1179 if (pguidCmdGroup)
1180 {
1181 if (IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject))
1182 {
1183 return InitializeNetTaskbarNotifications();
1184 }
1185 else
1186 {
1187 /* invoke status dialog */
1188 return ShowStatusDialogByCLSID(pguidCmdGroup);
1189 }
1190 }
1191 return S_OK;
1192 }
1193
1194 HRESULT WINAPI LanConnectStatusUI_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv)
1195 {
1196 TRACE("LanConnectStatusUI_Constructor\n");
1197
1198 if (!ppv)
1199 return E_POINTER;
1200
1201 if (pUnkOuter)
1202 return CLASS_E_NOAGGREGATION;
1203
1204 CLanStatus *pLanStatus = new CLanStatus;
1205 if (!pLanStatus)
1206 return E_OUTOFMEMORY;
1207
1208 pLanStatus->AddRef();
1209 static volatile CLanStatus *pCachedLanStatus = NULL;
1210 if (InterlockedCompareExchangePointer((void **)&pCachedLanStatus, pLanStatus, NULL) != NULL)
1211 pLanStatus->Release();
1212
1213 return ((CLanStatus*)pCachedLanStatus)->QueryInterface(riid, ppv);
1214 }
1215