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