#include <precomp.h>

/// CLASSID
/// {7007ACC5-3202-11D1-AAD2-00805FC1270E}
/// open network properties and wlan properties

typedef enum
{
    NET_TYPE_CLIENT = 1,
    NET_TYPE_SERVICE = 2,
    NET_TYPE_PROTOCOL = 3
}NET_TYPE;

typedef struct
{
    NET_TYPE Type;
    DWORD dwCharacteristics;
    LPWSTR szHelp;
    INetCfgComponent  *pNCfgComp;
    UINT NumPropDialogOpen;
}NET_ITEM, *PNET_ITEM;

typedef struct
{
    INetConnectionPropertyUi2 *lpVtbl;
    INetLanConnectionUiInfo * lpLanConUiInfoVtbl;
    INetConnectionConnectUi * lpNetConnectionConnectUi;
    INetConnection * pCon;
    INetCfgLock *NCfgLock;
    INetCfg * pNCfg;
    NETCON_PROPERTIES * pProperties;
    LONG ref;
}INetConnectionPropertyUiImpl, *LPINetConnectionPropertyUiImpl;

static __inline LPINetConnectionPropertyUiImpl impl_from_NetLanConnectionUiInfo(INetLanConnectionUiInfo *iface)
{
    return (LPINetConnectionPropertyUiImpl)((char *)iface - FIELD_OFFSET(INetConnectionPropertyUiImpl, lpLanConUiInfoVtbl));
}

static __inline LPINetConnectionPropertyUiImpl impl_from_NetConnectionConnectUi(INetConnectionConnectUi *iface)
{
    return (LPINetConnectionPropertyUiImpl)((char *)iface - FIELD_OFFSET(INetConnectionPropertyUiImpl, lpNetConnectionConnectUi));
}


HPROPSHEETPAGE
InitializePropertySheetPage(LPWSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle)
{
    PROPSHEETPAGEW ppage;

    memset(&ppage, 0x0, sizeof(PROPSHEETPAGEW));
    ppage.dwSize = sizeof(PROPSHEETPAGEW);
    ppage.dwFlags = PSP_DEFAULT;
    ppage.u.pszTemplate = resname;
    ppage.pfnDlgProc = dlgproc;
    ppage.lParam = lParam;
    ppage.hInstance = netshell_hInstance;
    if (szTitle)
    {
        ppage.dwFlags |= PSP_USETITLE;
        ppage.pszTitle = szTitle;
    }
    return CreatePropertySheetPageW(&ppage);
}

VOID
AddItemToListView(HWND hDlgCtrl, PNET_ITEM pItem, LPWSTR szName, BOOL bChecked)
{
    LVITEMW lvItem;

    ZeroMemory(&lvItem, sizeof(lvItem));
    lvItem.mask  = LVIF_TEXT | LVIF_PARAM;
    lvItem.pszText = szName;
    lvItem.lParam = (LPARAM)pItem;
    lvItem.iItem = ListView_GetItemCount(hDlgCtrl);
    lvItem.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
    ListView_SetCheckState(hDlgCtrl, lvItem.iItem, bChecked);
}

BOOL
GetINetCfgComponent(INetCfg * pNCfg, INetConnectionPropertyUiImpl * This, INetCfgComponent ** pOut)
{
    LPWSTR pName;
    HRESULT hr;
    INetCfgComponent * pNCg;
    ULONG Fetched;
    IEnumNetCfgComponent * pEnumCfg;

    hr = INetCfg_EnumComponents(pNCfg, &GUID_DEVCLASS_NET, &pEnumCfg);
    if (FAILED(hr))
    {
        return FALSE;
    }

    while(IEnumNetCfgComponent_Next(pEnumCfg, 1, &pNCg, &Fetched) == S_OK)
    {
       hr = INetCfgComponent_GetDisplayName(pNCg, &pName);
       if (SUCCEEDED(hr))
       {
           if (!_wcsicmp(pName, This->pProperties->pszwDeviceName))
           {
               *pOut = pNCg;
               IEnumNetCfgComponent_Release(pEnumCfg);
               return TRUE;
           }
           CoTaskMemFree(pName);
       }
       INetCfgComponent_Release(pNCg);
    }
    IEnumNetCfgComponent_Release(pEnumCfg);
    return FALSE;
}

VOID
EnumComponents(HWND hDlgCtrl, INetConnectionPropertyUiImpl * This, INetCfg * pNCfg, const GUID * CompGuid, UINT Type)
{
    HRESULT hr;
    IEnumNetCfgComponent * pENetCfg;
    INetCfgComponent  *pNCfgComp, *pAdapterCfgComp;
    INetCfgComponentBindings * pCompBind;
    ULONG Num;
    DWORD dwCharacteristics;
    LPOLESTR pDisplayName, pHelpText;
    PNET_ITEM pItem;
    BOOL bChecked;

    hr = INetCfg_EnumComponents(pNCfg, CompGuid, &pENetCfg);
    if (FAILED(hr))
    {
        INetCfg_Release(pNCfg);
        return;
    }
    while(IEnumNetCfgComponent_Next(pENetCfg, 1, &pNCfgComp, &Num) == S_OK)
    {
          hr = INetCfgComponent_GetCharacteristics(pNCfgComp, &dwCharacteristics);
          if (SUCCEEDED(hr) && (dwCharacteristics & NCF_HIDDEN))
          {
              INetCfgComponent_Release(pNCfgComp);
              continue;
          }
          pDisplayName = NULL;
          pHelpText = NULL;
          hr = INetCfgComponent_GetDisplayName(pNCfgComp, &pDisplayName);
          hr = INetCfgComponent_GetHelpText(pNCfgComp, &pHelpText);
          bChecked = TRUE; //ReactOS hack
          hr = INetCfgComponent_QueryInterface(pNCfgComp, &IID_INetCfgComponentBindings, (LPVOID*)&pCompBind);
          if (SUCCEEDED(hr))
          {
              if (GetINetCfgComponent(pNCfg, This, &pAdapterCfgComp))
              {
                  hr = INetCfgComponentBindings_IsBoundTo(pCompBind, pAdapterCfgComp);
                  if (hr == S_OK)
                      bChecked = TRUE;
                  else
                      bChecked = FALSE;
                  INetCfgComponent_Release(pAdapterCfgComp);
                  INetCfgComponentBindings_Release(pCompBind);
              }
          }
          pItem = CoTaskMemAlloc(sizeof(NET_ITEM));
          if (!pItem)
              continue;
          pItem->dwCharacteristics = dwCharacteristics;
          pItem->szHelp = pHelpText;
          pItem->Type = Type;
          pItem->pNCfgComp = pNCfgComp;
          pItem->NumPropDialogOpen = 0;


          AddItemToListView(hDlgCtrl, pItem, pDisplayName, bChecked);
          CoTaskMemFree(pDisplayName);
    }
    IEnumNetCfgComponent_Release(pENetCfg);
}


VOID
InitializeLANPropertiesUIDlg(HWND hwndDlg, INetConnectionPropertyUiImpl * This)
{
    HRESULT hr;
    INetCfg * pNCfg;
    INetCfgLock * pNCfgLock;
    HWND hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMPONENTSLIST);
    LVCOLUMNW lc;
    RECT rc;
    DWORD dwStyle;
    LPWSTR pDisplayName;
    LVITEMW li;

    SendDlgItemMessageW(hwndDlg, IDC_NETCARDNAME, WM_SETTEXT, 0, (LPARAM)This->pProperties->pszwDeviceName);
    if (This->pProperties->dwCharacter & NCCF_SHOW_ICON)
    {
        /* check show item on taskbar*/
        SendDlgItemMessageW(hwndDlg, IDC_SHOWTASKBAR, BM_SETCHECK, BST_CHECKED, 0);
    }
    if (This->pProperties->dwCharacter & NCCF_NOTIFY_DISCONNECTED)
    {
        /* check notify item */
        SendDlgItemMessageW(hwndDlg, IDC_NOTIFYNOCONNECTION, BM_SETCHECK, BST_CHECKED, 0);
    }

    memset(&lc, 0, sizeof(LV_COLUMN));
    lc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
    lc.fmt = LVCFMT_FIXED_WIDTH;
    if (GetClientRect(hDlgCtrl, &rc))
    {
        lc.mask |= LVCF_WIDTH;
        lc.cx = rc.right - rc.left;
    }
    lc.pszText    = L"";
    (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&lc);
    dwStyle = (DWORD) SendMessage(hDlgCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
    dwStyle = dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES;
    SendMessage(hDlgCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);



    hr = CoCreateInstance(&CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, &IID_INetCfg, (LPVOID*)&pNCfg);
    if (FAILED(hr))
        return;

    hr = INetCfgLock_QueryInterface(pNCfg, &IID_INetCfgLock, (LPVOID*)&pNCfgLock);
    hr = INetCfgLock_AcquireWriteLock(pNCfgLock, 100, L"", &pDisplayName);
    if (hr == S_FALSE)
    {
        CoTaskMemFree(pDisplayName);
        return;
    }

    This->NCfgLock = pNCfgLock;
    hr = INetCfg_Initialize(pNCfg, NULL);
    if (FAILED(hr))
    {
        INetCfg_Release(pNCfg);
        return;
    }

    EnumComponents(hDlgCtrl, This, pNCfg, &GUID_DEVCLASS_NETCLIENT, NET_TYPE_CLIENT);
    EnumComponents(hDlgCtrl, This, pNCfg, &GUID_DEVCLASS_NETSERVICE, NET_TYPE_SERVICE);
    EnumComponents(hDlgCtrl, This, pNCfg, &GUID_DEVCLASS_NETTRANS, NET_TYPE_PROTOCOL);
    This->pNCfg = pNCfg;

    ZeroMemory(&li, sizeof(li));
    li.mask = LVIF_STATE;
    li.stateMask = (UINT)-1;
    li.state = LVIS_FOCUSED|LVIS_SELECTED;
    (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
}

VOID
ShowNetworkComponentProperties(
    HWND hwndDlg,
    INetConnectionPropertyUiImpl * This)
{
    LVITEMW lvItem;
    HWND hDlgCtrl;
    UINT Index, Count;
    HRESULT hr;
    INetCfgComponent * pNCfgComp;
    PNET_ITEM pItem;

    hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMPONENTSLIST);
    Count = ListView_GetItemCount(hDlgCtrl);
    if (!Count)
        return;

    ZeroMemory(&lvItem, sizeof(LVITEMW));
    lvItem.mask = LVIF_PARAM | LVIF_STATE;
    lvItem.stateMask = (UINT)-1;
    for (Index = 0; Index < Count; Index++)
    {
        lvItem.iItem = Index;
        if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&lvItem))
        {
           if (lvItem.state & LVIS_SELECTED)
               break;
        }
    }

    if (!(lvItem.state & LVIS_SELECTED))
    {
        return;
    }

    pItem = (PNET_ITEM)lvItem.lParam;
    pNCfgComp = (INetCfgComponent*) pItem->pNCfgComp;
    hr = INetCfgComponent_RaisePropertyUi(pNCfgComp, GetParent(hwndDlg), NCRP_QUERY_PROPERTY_UI, (IUnknown*)This);
    if (SUCCEEDED(hr))
    {
        hr = INetCfgComponent_RaisePropertyUi(pNCfgComp, GetParent(hwndDlg), NCRP_SHOW_PROPERTY_UI, (IUnknown*)This);
    }
}


INT_PTR
CALLBACK
LANPropertiesUIDlg(
    HWND hwndDlg,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
)
{
    PROPSHEETPAGE *page;
    LPNMLISTVIEW lppl;
    LVITEMW li;
    PNET_ITEM pItem;
    INetConnectionPropertyUiImpl * This;
    LPPSHNOTIFY lppsn;
    DWORD dwShowIcon;
    HRESULT hr;
    WCHAR szKey[200];
    LPOLESTR pStr;
    HKEY hKey;

    switch(uMsg)
    {
        case WM_INITDIALOG:
            page = (PROPSHEETPAGE*)lParam;
            This = (INetConnectionPropertyUiImpl*)page->lParam;
            InitializeLANPropertiesUIDlg(hwndDlg, This);
            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
            return TRUE;
        case WM_NOTIFY:
            lppl = (LPNMLISTVIEW) lParam;
            lppsn = (LPPSHNOTIFY) lParam;
            if (lppsn->hdr.code == PSN_APPLY)
            {
                This = (INetConnectionPropertyUiImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
                if (This->pNCfg)
                {
                    hr = INetCfg_Apply(This->pNCfg);
                    if (FAILED(hr))
                        return PSNRET_INVALID;
                }

                if (SendDlgItemMessageW(hwndDlg, IDC_SHOWTASKBAR, BM_GETCHECK, 0, 0) == BST_CHECKED)
                    dwShowIcon = 1;
                else
                    dwShowIcon = 0;


                if (StringFromCLSID(&This->pProperties->guidId, &pStr) == ERROR_SUCCESS)
                {
                    swprintf(szKey, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pStr);
                    CoTaskMemFree(pStr);
                    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKey, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
                    {
                        RegSetValueExW(hKey, L"ShowIcon", 0, REG_DWORD, (LPBYTE)&dwShowIcon, sizeof(DWORD));
                        RegCloseKey(hKey);
                    }
                }

                return PSNRET_NOERROR;
            }
#if 0
            else if (lppsn->hdr.code == PSN_CANCEL)
            {
                This = (INetConnectionPropertyUiImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
                if (This->pNCfg)
                {
                    hr = INetCfg_Cancel(This->pNCfg);
                    if (SUCCEEDED(hr))
                        return PSNRET_NOERROR;
                    else
                        return PSNRET_INVALID;
                }
                return PSNRET_NOERROR;
            }
#endif
            if (lppl->hdr.code == LVN_ITEMCHANGING)
            {
                    ZeroMemory(&li, sizeof(li));
                    li.mask = LVIF_PARAM;
                    li.iItem = lppl->iItem;
                    if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&li))
                        return TRUE;

                    pItem = (PNET_ITEM)li.lParam;
                    if (!pItem)
                        return TRUE;

                    if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
                    {
                        /* new focused item */
                        if (pItem->dwCharacteristics & NCF_NOT_USER_REMOVABLE)
                            EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALL), FALSE);
                        else
                            EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALL), TRUE);

                        if (pItem->dwCharacteristics & NCF_HAS_UI)
                            EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTIES), TRUE);
                        else
                            EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTIES), FALSE);

                        SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_SETTEXT, 0, (LPARAM)pItem->szHelp);
                    }
             }
             break;
        case WM_COMMAND:
            if (LOWORD(wParam) == IDC_PROPERTIES)
            {
                This = (INetConnectionPropertyUiImpl*) GetWindowLongPtr(hwndDlg, DWLP_USER);
                ShowNetworkComponentProperties(hwndDlg, This);
                return FALSE;
            }
            break;
    }
    return FALSE;
}

static
HRESULT
WINAPI
INetConnectionPropertyUi2_fnQueryInterface(
    INetConnectionPropertyUi2 * iface,
    REFIID iid,
    LPVOID * ppvObj)
{
    LPOLESTR pStr;
    INetConnectionPropertyUiImpl * This =  (INetConnectionPropertyUiImpl*)iface;
    *ppvObj = NULL;

    if (IsEqualIID (iid, &IID_IUnknown) ||
        IsEqualIID (iid, &IID_INetConnectionPropertyUi) ||
        IsEqualIID (iid, &IID_INetConnectionPropertyUi2))
    {
        *ppvObj = This;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    else if (IsEqualIID(iid, &IID_INetLanConnectionUiInfo))
    {
        *ppvObj = &This->lpLanConUiInfoVtbl;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    else if (IsEqualIID(iid, &IID_INetConnectionConnectUi))
    {
        *ppvObj = &This->lpNetConnectionConnectUi;
        IUnknown_AddRef(iface);
        return S_OK;
    }

    StringFromCLSID(iid, &pStr);
    MessageBoxW(NULL, pStr, L"INetConnectionPropertyUi_fnQueryInterface", MB_OK);
    CoTaskMemFree(pStr);
    return E_NOINTERFACE;
}

static
ULONG
WINAPI
INetConnectionPropertyUi2_fnAddRef(
    INetConnectionPropertyUi2 * iface)
{
    INetConnectionPropertyUiImpl * This =  (INetConnectionPropertyUiImpl*)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    return refCount;
}

static
ULONG
WINAPI
INetConnectionPropertyUi2_fnRelease(
    INetConnectionPropertyUi2 * iface)
{
    INetConnectionPropertyUiImpl * This =  (INetConnectionPropertyUiImpl*)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    if (!refCount) 
    {
        if (This->pNCfg)
        {
            INetCfg_Uninitialize(This->pNCfg);
            INetCfg_Release(This->pNCfg);
        }
        if (This->NCfgLock)
        {
            INetCfgLock_Release(This->NCfgLock);
        }
        if (This->pProperties)
        {
            NcFreeNetconProperties(This->pProperties);
        }
        CoTaskMemFree (This);
    }
    return refCount;
}

static
HRESULT
WINAPI
INetConnectionPropertyUi2_fnSetConnection(
    INetConnectionPropertyUi2 * iface,
    INetConnection *pCon)
{
    INetConnectionPropertyUiImpl * This =  (INetConnectionPropertyUiImpl*)iface;

    if (!pCon)
        return E_POINTER;

    if (This->pCon)
        INetConnection_Release(This->pCon);

    This->pCon = pCon;
    INetConnection_AddRef(This->pCon);
    return S_OK;
}

static
HRESULT
WINAPI
INetConnectionPropertyUi2_fnAddPages(
    INetConnectionPropertyUi2 * iface,
    HWND hwndParent, 
    LPFNADDPROPSHEETPAGE pfnAddPage,
    LPARAM lParam)
{
    HPROPSHEETPAGE hProp;
    BOOL ret;
    HRESULT hr = E_FAIL;
    INITCOMMONCONTROLSEX initEx;
    INetConnectionPropertyUiImpl * This =  (INetConnectionPropertyUiImpl*)iface;


    initEx.dwSize = sizeof(initEx);
    initEx.dwICC = ICC_LISTVIEW_CLASSES;
    if(!InitCommonControlsEx(&initEx))
        return E_FAIL;

    hr = INetConnection_GetProperties(This->pCon, &This->pProperties);
    if (FAILED(hr))
        return hr;

	hProp = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_NETPROPERTIES), LANPropertiesUIDlg, (LPARAM)This, This->pProperties->pszwName);
    if (hProp)
    {
        ret = (*pfnAddPage)(hProp, lParam);
        if (ret)
        {
            hr = NOERROR;
        }
        else
        {
            DestroyPropertySheetPage(hProp);
        }
    }
    return hr;
}

static
HRESULT
WINAPI
INetConnectionPropertyUi2_fnGetIcon(
    INetConnectionPropertyUi2 * iface,
    DWORD dwSize,
    HICON *phIcon)
{
    return E_NOTIMPL;
}

static const INetConnectionPropertyUi2Vtbl vt_NetConnectionPropertyUi =
{
    INetConnectionPropertyUi2_fnQueryInterface,
    INetConnectionPropertyUi2_fnAddRef,
    INetConnectionPropertyUi2_fnRelease,
    INetConnectionPropertyUi2_fnSetConnection,
    INetConnectionPropertyUi2_fnAddPages,
    INetConnectionPropertyUi2_fnGetIcon,
};

static
HRESULT
WINAPI
INetLanConnectionUiInfo_fnQueryInterface(
    INetLanConnectionUiInfo * iface,
    REFIID iid,
    LPVOID * ppvObj)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetLanConnectionUiInfo(iface);
    return INetConnectionPropertyUi_QueryInterface((INetConnectionPropertyUi*)This, iid, ppvObj);
}

static
ULONG
WINAPI
INetLanConnectionUiInfo_fnAddRef(
    INetLanConnectionUiInfo * iface)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetLanConnectionUiInfo(iface);
    return INetConnectionPropertyUi_AddRef((INetConnectionPropertyUi*)This);
}

static
ULONG
WINAPI
INetLanConnectionUiInfo_fnRelease(
    INetLanConnectionUiInfo * iface)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetLanConnectionUiInfo(iface);
    return INetConnectionPropertyUi_Release((INetConnectionPropertyUi*)This);
}

static
HRESULT
WINAPI
INetLanConnectionUiInfo_fnGetDeviceGuid(
    INetLanConnectionUiInfo * iface,
    GUID * pGuid)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetLanConnectionUiInfo(iface);
    CopyMemory(pGuid, &This->pProperties->guidId, sizeof(GUID));
    return S_OK;
}

static const INetLanConnectionUiInfoVtbl vt_NetLanConnectionUiInfo =
{
    INetLanConnectionUiInfo_fnQueryInterface,
    INetLanConnectionUiInfo_fnAddRef,
    INetLanConnectionUiInfo_fnRelease,
    INetLanConnectionUiInfo_fnGetDeviceGuid,
};

static
HRESULT
WINAPI
INetConnectionConnectUi_fnQueryInterface(
    INetConnectionConnectUi * iface,
    REFIID iid,
    LPVOID * ppvObj)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetConnectionConnectUi(iface);
    return INetConnectionPropertyUi_QueryInterface((INetConnectionPropertyUi*)This, iid, ppvObj);
}

static
ULONG
WINAPI
INetConnectionConnectUi_fnAddRef(
    INetConnectionConnectUi * iface)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetConnectionConnectUi(iface);
    return INetConnectionPropertyUi_AddRef((INetConnectionPropertyUi*)This);
}

static
ULONG
WINAPI
INetConnectionConnectUi_fnRelease(
    INetConnectionConnectUi * iface)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetConnectionConnectUi(iface);
    return INetConnectionPropertyUi_Release((INetConnectionPropertyUi*)This);
}

static
HRESULT
WINAPI
INetConnectionConnectUi_fnSetConnection(
    INetConnectionConnectUi * iface,
    INetConnection* pCon)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetConnectionConnectUi(iface);
    if (This->pCon)
        INetConnection_Release(This->pCon);

    if (!pCon)
        return E_POINTER;

    This->pCon = pCon;
    INetConnection_AddRef(pCon);
    return S_OK;
}

static
HRESULT
WINAPI
INetConnectionConnectUi_fnConnect(
    INetConnectionConnectUi * iface,
    HWND hwndParent,
    DWORD dwFlags)
{
    INetConnectionPropertyUiImpl * This =  impl_from_NetConnectionConnectUi(iface);

    if (!This->pCon)
        return E_POINTER; //FIXME


    if (dwFlags & NCUC_NO_UI)
    {
        return INetConnection_Connect(This->pCon);
    }

    return E_FAIL;
}

static
HRESULT
WINAPI
INetConnectionConnectUi_fnDisconnect(
    INetConnectionConnectUi * iface,
    HWND hwndParent,
    DWORD dwFlags)
{
	WCHAR szBuffer[100];
    swprintf(szBuffer, L"INetConnectionConnectUi_fnDisconnect flags %x\n", dwFlags);
	MessageBoxW(NULL, szBuffer, NULL, MB_OK);

    return S_OK;
}


static const INetConnectionConnectUiVtbl vt_NetConnectionConnectUi =
{
    INetConnectionConnectUi_fnQueryInterface,
    INetConnectionConnectUi_fnAddRef,
    INetConnectionConnectUi_fnRelease,
    INetConnectionConnectUi_fnSetConnection,
    INetConnectionConnectUi_fnConnect,
    INetConnectionConnectUi_fnDisconnect,

};



HRESULT WINAPI LanConnectUI_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
{
    INetConnectionPropertyUiImpl * This;

    if (!ppv)
        return E_POINTER;

    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    This = (INetConnectionPropertyUiImpl *) CoTaskMemAlloc(sizeof (INetConnectionPropertyUiImpl));
    if (!This)
        return E_OUTOFMEMORY;

    This->ref = 1;
    This->pCon = NULL;
    This->pNCfg = NULL;
    This->NCfgLock = NULL;
    This->pProperties = NULL;
    This->lpVtbl = (INetConnectionPropertyUi2*)&vt_NetConnectionPropertyUi;
    This->lpLanConUiInfoVtbl = (INetLanConnectionUiInfo*)&vt_NetLanConnectionUiInfo;
    This->lpNetConnectionConnectUi = (INetConnectionConnectUi*)&vt_NetConnectionConnectUi;

    if (!SUCCEEDED (INetConnectionPropertyUi2_fnQueryInterface ((INetConnectionPropertyUi2*)This, riid, ppv)))
    {
        IUnknown_Release((IUnknown*)This);
        return E_NOINTERFACE;
    }

    IUnknown_Release((IUnknown*)This);
    return S_OK;
}
