diff --git a/reactos/dll/win32/netshell/classfactory.c b/reactos/dll/win32/netshell/classfactory.c new file mode 100644 index 00000000000..7cd61c62586 --- /dev/null +++ b/reactos/dll/win32/netshell/classfactory.c @@ -0,0 +1,125 @@ +#include + +typedef struct +{ + const IClassFactoryVtbl *lpVtbl; + LONG ref; + CLSID *rclsid; + LPFNCREATEINSTANCE lpfnCI; + const IID * riidInst; +} IClassFactoryImpl; + + +static +HRESULT +WINAPI +IClassFactory_fnQueryInterface( + LPCLASSFACTORY iface, + REFIID riid, + LPVOID *ppvObj) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + *ppvObj = NULL; + + if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) + { + *ppvObj = This; + InterlockedIncrement(&This->ref); + return S_OK; + } + return E_NOINTERFACE; +} + +static +ULONG +WINAPI +IClassFactory_fnAddRef( + LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +static +ULONG +WINAPI +IClassFactory_fnRelease( + LPCLASSFACTORY iface) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + if (!refCount) + { + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return refCount; +} + +static +HRESULT +WINAPI +IClassFactory_fnCreateInstance( + LPCLASSFACTORY iface, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID *ppvObject) +{ + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + *ppvObject = NULL; + + if ( This->riidInst==NULL || IsEqualCLSID(riid, This->riidInst) || IsEqualCLSID(riid, &IID_IUnknown) ) + { + return This->lpfnCI(pUnkOuter, riid, ppvObject); + } + + return E_NOINTERFACE; +} + +static +HRESULT +WINAPI IClassFactory_fnLockServer( + LPCLASSFACTORY iface, + BOOL fLock) +{ + //IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return E_NOTIMPL; +} + + +static const IClassFactoryVtbl dclfvt = +{ + IClassFactory_fnQueryInterface, + IClassFactory_fnAddRef, + IClassFactory_fnRelease, + IClassFactory_fnCreateInstance, + IClassFactory_fnLockServer +}; + + +IClassFactory * +IClassFactory_fnConstructor( + LPFNCREATEINSTANCE lpfnCI, + PLONG pcRefDll, + REFIID riidInst) +{ + IClassFactoryImpl* lpclf; + + lpclf = HeapAlloc(GetProcessHeap(),0,sizeof(IClassFactoryImpl)); + lpclf->ref = 1; + lpclf->lpVtbl = &dclfvt; + lpclf->lpfnCI = lpfnCI; + + if (pcRefDll) + InterlockedIncrement(pcRefDll); + lpclf->riidInst = riidInst; + + return (LPCLASSFACTORY)lpclf; +} + + diff --git a/reactos/dll/win32/netshell/enumlist.c b/reactos/dll/win32/netshell/enumlist.c new file mode 100644 index 00000000000..814ea42e662 --- /dev/null +++ b/reactos/dll/win32/netshell/enumlist.c @@ -0,0 +1,364 @@ +#include + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + +typedef struct tagGUIDStruct +{ + BYTE dummy; /* offset 01 is unknown */ + GUID guid; /* offset 02 */ +} GUIDStruct; + +#define PT_GUID 0x1F + +typedef struct tagPIDLDATA +{ + BYTE type; /*00*/ + union + { + struct tagGUIDStruct guid; + struct tagVALUEStruct value; + }u; +} PIDLDATA, *LPPIDLDATA; + +typedef struct tagENUMLIST +{ + struct tagENUMLIST *pNext; + LPITEMIDLIST pidl; + +}ENUMLIST, *LPENUMLIST; + +typedef struct +{ + const IEnumIDListVtbl *lpVtbl; + LONG ref; + LPENUMLIST mpFirst; + LPENUMLIST mpLast; + LPENUMLIST mpCurrent; + +} IEnumIDListImpl; + +/************************************************************************** + * AddToEnumList() + */ +BOOL +AddToEnumList( + IEnumIDList * iface, + LPITEMIDLIST pidl) +{ + LPENUMLIST pNew; + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + + + if (!iface || !pidl) + return FALSE; + + pNew = (LPENUMLIST)SHAlloc(sizeof(ENUMLIST)); + if(pNew) + { + pNew->pNext = NULL; + pNew->pidl = pidl; + + if(!This->mpFirst) + { + This->mpFirst = pNew; + This->mpCurrent = pNew; + } + + if(This->mpLast) + { + /*add the new item to the end of the list */ + This->mpLast->pNext = pNew; + } + + /*update the last item pointer */ + This->mpLast = pNew; + return TRUE; + } + return FALSE; +} + +static +HRESULT +WINAPI +IEnumIDList_fnQueryInterface( + IEnumIDList * iface, + REFIID riid, + LPVOID *ppvObj) +{ + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + + *ppvObj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumIDList)) + { + *ppvObj = This; + IEnumIDList_AddRef((IEnumIDList*)*ppvObj); + return S_OK; + } + + return E_NOINTERFACE; +} + +static +ULONG +WINAPI +IEnumIDList_fnAddRef( + IEnumIDList * iface) +{ + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +static +ULONG +WINAPI IEnumIDList_fnRelease( + IEnumIDList * iface) +{ + LPENUMLIST pDelete; + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + if (!refCount) + { + while(This->mpFirst) + { + pDelete = This->mpFirst; + This->mpFirst = pDelete->pNext; + SHFree(pDelete->pidl); + SHFree(pDelete); + } + HeapFree(GetProcessHeap(),0,This); + } + return refCount; +} + +static +HRESULT +WINAPI +IEnumIDList_fnNext( + IEnumIDList * iface, + ULONG celt, + LPITEMIDLIST * rgelt, + ULONG *pceltFetched) +{ + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + + ULONG i; + HRESULT hr = S_OK; + LPITEMIDLIST temp; + + if(pceltFetched) + *pceltFetched = 0; + + *rgelt=0; + + if(celt > 1 && !pceltFetched) + { + return E_INVALIDARG; + } + + if(celt > 0 && !This->mpCurrent) + { + return S_FALSE; + } + + for(i = 0; i < celt; i++) + { + if(!(This->mpCurrent)) + break; + + temp = ILClone(This->mpCurrent->pidl); + rgelt[i] = temp; + This->mpCurrent = This->mpCurrent->pNext; + } + + if(pceltFetched) + { + *pceltFetched = i; + } + + return hr; +} + +static +HRESULT +WINAPI +IEnumIDList_fnSkip( + IEnumIDList * iface,ULONG celt) +{ + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + + DWORD dwIndex; + HRESULT hr = S_OK; + + for(dwIndex = 0; dwIndex < celt; dwIndex++) + { + if(!This->mpCurrent) + { + hr = S_FALSE; + break; + } + This->mpCurrent = This->mpCurrent->pNext; + } + return hr; +} + +static +HRESULT +WINAPI +IEnumIDList_fnReset( + IEnumIDList * iface) +{ + IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + + This->mpCurrent = This->mpFirst; + return S_OK; +} + +static +HRESULT +WINAPI +IEnumIDList_fnClone( + IEnumIDList * iface, + LPENUMIDLIST * ppenum) +{ + //IEnumIDListImpl *This = (IEnumIDListImpl *)iface; + + return E_NOTIMPL; +} + +static const IEnumIDListVtbl eidlvt = +{ + IEnumIDList_fnQueryInterface, + IEnumIDList_fnAddRef, + IEnumIDList_fnRelease, + IEnumIDList_fnNext, + IEnumIDList_fnSkip, + IEnumIDList_fnReset, + IEnumIDList_fnClone, +}; + +IEnumIDList * IEnumIDList_Constructor(void) +{ + IEnumIDListImpl *lpeidl = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(IEnumIDListImpl)); + + if (lpeidl) + { + lpeidl->ref = 1; + lpeidl->lpVtbl = &eidlvt; + } + + return (IEnumIDList*)lpeidl; +} + +LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl) +{ + if(pidl && pidl->mkid.cb != 0x00) + return (LPPIDLDATA) &(pidl->mkid.abID); + return NULL; +} + +LPITEMIDLIST _ILAlloc(BYTE type, unsigned int size) +{ + LPITEMIDLIST pidlOut = NULL; + + pidlOut = SHAlloc(size + 5); + if(pidlOut) + { + LPPIDLDATA pData; + + ZeroMemory(pidlOut, size + 5); + pidlOut->mkid.cb = size + 3; + pData = _ILGetDataPointer(pidlOut); + if (pData) + pData->type = type; + + } + + return pidlOut; +} + +LPITEMIDLIST _ILCreateNetConnect() +{ + LPITEMIDLIST pidlOut; + + pidlOut = _ILAlloc(PT_GUID, sizeof(GUIDStruct)); + if (pidlOut) + { + LPPIDLDATA pData = _ILGetDataPointer(pidlOut); + + memcpy(&(pData->u.guid.guid), &CLSID_NetworkConnections, sizeof(GUID)); + } + else + { + pidlOut = NULL; + } + return pidlOut; +} + +IID* _ILGetGUIDPointer(LPCITEMIDLIST pidl) +{ + LPPIDLDATA pdata =_ILGetDataPointer(pidl); + + if (!pdata) + return NULL; + + if (pdata->type != PT_GUID) + return NULL; + else + return &(pdata->u.guid.guid); + +} + +BOOL _ILIsNetConnect(LPCITEMIDLIST pidl) +{ + REFIID iid = _ILGetGUIDPointer(pidl); + + if (iid) + return IsEqualIID(iid, &CLSID_NetworkConnections); + return FALSE; +} + +LPITEMIDLIST ILCreateNetConnectItem(MIB_IFROW * pRow, LPWSTR szName, LPWSTR szAdapterName) +{ + PIDLDATA tmp; + LPITEMIDLIST pidl; + VALUEStruct * p; + int size = sizeof(struct tagVALUEStruct); + + tmp.type = 0x00; + tmp.u.value.dummy = 0xFF; + + tmp.u.value.dwOperStatus = pRow->dwOperStatus; + tmp.u.value.dwType = pRow->dwType; + tmp.u.value.dwNameLength = wcslen(szName) + 1; + + size += (tmp.u.value.dwNameLength + wcslen(szAdapterName)) * sizeof(WCHAR); + + pidl = (LPITEMIDLIST)SHAlloc(size + 4); + if (!pidl) + return pidl; + + pidl->mkid.cb = size+2; + memcpy(pidl->mkid.abID, &tmp, 2+sizeof(struct tagVALUEStruct)); + + p = &((PIDLDATA*)pidl->mkid.abID)->u.value; + wcscpy(&p->szName[0], szName); + wcscpy(p->szName + tmp.u.value.dwNameLength, szAdapterName); + + *(WORD*)((char*)pidl+(size+2)) = 0; + return pidl; +} + +VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl) +{ + LPPIDLDATA pdata = _ILGetDataPointer(pidl); + + if (pdata && pdata->type==0x00) + return (VALUEStruct*)&(pdata->u.value); + + return NULL; +} diff --git a/reactos/dll/win32/netshell/lang/.gitignore b/reactos/dll/win32/netshell/lang/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/reactos/dll/win32/netshell/netshell.c b/reactos/dll/win32/netshell/netshell.c new file mode 100644 index 00000000000..783f6d90c95 --- /dev/null +++ b/reactos/dll/win32/netshell/netshell.c @@ -0,0 +1,144 @@ +#include "precomp.h" + +HINSTANCE netshell_hInstance; +const GUID CLSID_NetworkConnections = {0x7007ACC7, 0x3202, 0x11D1, {0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E}}; +const GUID GUID_DEVCLASS_NET = {0x4d36e972, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; +static const WCHAR szNetConnectClass[] = L"CLSID\\{7007ACC7-3202-11D1-AAD2-00805FC1270E}"; +static const WCHAR szNamespaceKey[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\{7007ACC7-3202-11D1-AAD2-00805FC1270E}"; + +static INTERFACE_TABLE InterfaceTable[] = +{ + { + &CLSID_NetworkConnections, + ISF_NetConnect_Constructor + }, + { + NULL, + NULL + } +}; + + +BOOL +WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + netshell_hInstance = hinstDLL; + DisableThreadLibraryCalls(netshell_hInstance); + break; + default: + break; + } + + return TRUE; +} + +HRESULT +WINAPI +DllCanUnloadNow(void) +{ + return S_FALSE; +} + +STDAPI +DllRegisterServer(void) +{ + HKEY hKey, hSubKey; + WCHAR szName[MAX_PATH] = {0}; + WCHAR szNet[20]; + UINT Length, Offset; + + if (RegCreateKeyExW(HKEY_CLASSES_ROOT, szNetConnectClass, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) + return SELFREG_E_CLASS; + + if (LoadStringW(netshell_hInstance, IDS_NETWORKCONNECTION, szName, MAX_PATH)) + { + szName[MAX_PATH-1] = L'\0'; + RegSetValueW(hKey, NULL, REG_SZ, szName, (wcslen(szName)+1) * sizeof(WCHAR)); + } + + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szNamespaceKey, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) + { + RegSetValueW(hSubKey, NULL, REG_SZ, szName, (wcslen(szName)+1) * sizeof(WCHAR)); + RegCloseKey(hSubKey); + } + + Length = swprintf(szNet, L",-%u", IDS_NETWORKCONNECTION); + Offset = GetModuleFileNameW(netshell_hInstance, &szName[1], MAX_PATH); + if (Offset + Length + 2 < MAX_PATH) + { + /* set localized name */ + szName[0] = L'@'; + wcscpy(&szName[Offset+1], szNet); + RegSetValueExW(hKey, L"LocalizedString", 0, REG_SZ, (const LPBYTE)szName, (wcslen(szName)+1) * sizeof(WCHAR)); + } + + szName[Offset+1] = L'\0'; + + /* store default icon */ + if (RegCreateKeyExW(hKey, L"DefaultIcon", 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) + { + RegSetValueW(hSubKey, NULL, REG_SZ, &szName[1], (Offset+1) * sizeof(WCHAR)); + RegCloseKey(hSubKey); + } + if (RegCreateKeyExW(hKey, L"InProcServer32", 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) + { + RegSetValueW(hSubKey, NULL, REG_SZ, &szName[1], (Offset+1) * sizeof(WCHAR)); + RegCloseKey(hSubKey); + } + + if (RegCreateKeyExW(hKey, L"ShellFolder", 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS) + { + DWORD dwAttributes = SFGAO_FOLDER; + RegSetValueExW(hSubKey, L"Attributes",0, REG_BINARY, (const LPBYTE)&dwAttributes, sizeof(DWORD)); + } + + return S_OK; +} + +STDAPI +DllUnregisterServer(void) +{ + SHDeleteKeyW(HKEY_CLASSES_ROOT, szNetConnectClass); + SHDeleteKeyW(HKEY_LOCAL_MACHINE, szNamespaceKey); + return S_OK; +} + +STDAPI +DllGetClassObject( + REFCLSID rclsid, + REFIID riid, + LPVOID* ppv +) +{ + UINT i; + HRESULT hres = E_OUTOFMEMORY; + IClassFactory * pcf = NULL; + + if (!ppv) + return E_INVALIDARG; + + *ppv = NULL; + + for (i = 0; InterfaceTable[i].riid; i++) + { + if (IsEqualIID(InterfaceTable[i].riid, rclsid)) + { + pcf = IClassFactory_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL); + break; + } + } + + if (!pcf) + { + return CLASS_E_CLASSNOTAVAILABLE; + } + + hres = IClassFactory_QueryInterface(pcf, riid, ppv); + IClassFactory_Release(pcf); + + return hres; +} diff --git a/reactos/dll/win32/netshell/netshell.rbuild b/reactos/dll/win32/netshell/netshell.rbuild new file mode 100644 index 00000000000..eaa97952d6f --- /dev/null +++ b/reactos/dll/win32/netshell/netshell.rbuild @@ -0,0 +1,27 @@ + + + + . + 0x600 + 0x600 + 0x600 + + shlwapi + shell32 + version + iphlpapi + kernel32 + wine + ole32 + user32 + uuid + advapi32 + setupapi + precomp.h + netshell.c + shfldr_netconnect.c + enumlist.c + netshell.rc + classfactory.c + netshell.spec + diff --git a/reactos/dll/win32/netshell/netshell.rc b/reactos/dll/win32/netshell/netshell.rc new file mode 100644 index 00000000000..aa99634b923 --- /dev/null +++ b/reactos/dll/win32/netshell/netshell.rc @@ -0,0 +1,10 @@ +#include +#include "shlobj.h" +#include "resource.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +IDI_SHELL_NETWORK_FOLDER ICON "res/netshell.ico" + +#include "lang/de-DE.rc" +#include "lang/en-US.rc" diff --git a/reactos/dll/win32/netshell/netshell.spec b/reactos/dll/win32/netshell/netshell.spec new file mode 100644 index 00000000000..e0ebfe62459 --- /dev/null +++ b/reactos/dll/win32/netshell/netshell.spec @@ -0,0 +1,34 @@ + +1 stub DoInitialCleanup +2 stdcall DllCanUnloadNow() +3 stdcall DllGetClassObject(ptr ptr ptr) +4 stdcall DllRegisterServer() +5 stdcall DllUnregisterServer() +6 stub HrCreateDesktopIcon +7 stub HrGetAnswerFileParametersForNetCard +8 stub HrGetExtendedStatusFromNCS +9 stub HrGetIconFromMediaType +10 stub HrGetInstanceGuidOfPreNT5NetCardInstance +11 stub HrGetNetConExtendedStatusFromGuid +12 stub HrGetNetConExtendedStatusFromINetConnection +13 stub HrGetStatusStringFromNetConExtendedStatus +14 stub HrIsIpStateCheckingEnabled +15 stub HrLaunchConnection +16 stub HrLaunchConnectionEx +17 stub HrLaunchNetworkOptionalComponents +18 stub HrOemUpgrade +19 stub HrRenameConnection +20 stub HrRunWizard +21 stub InvokeDunFile +22 stub NcFreeNetconProperties +23 stub NcIsValidConnectionName +24 stub NetSetupAddRasConnection +25 stub NetSetupFinishInstall +26 stub NetSetupInstallSoftware +27 stub NetSetupPrepareSysPrep +28 stub NetSetupRequestWizardPages +29 stub NetSetupSetProgressCallback +30 stub NormalizeExtendedStatus +31 stub RaiseSupportDialog +32 stub RepairConnection +33 stub StartNCW diff --git a/reactos/dll/win32/netshell/precomp.h b/reactos/dll/win32/netshell/precomp.h new file mode 100644 index 00000000000..07870a6c112 --- /dev/null +++ b/reactos/dll/win32/netshell/precomp.h @@ -0,0 +1,82 @@ +#ifndef _PRECOMP_H__ +#define _PRECOMP_H__ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "resource.h" + +typedef struct { + int colnameid; + int pcsFlags; + int fmt; + int cxChar; +} shvheader; + +typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject); +typedef struct { + REFIID riid; + LPFNCREATEINSTANCE lpfnCI; +} INTERFACE_TABLE; + +typedef struct tagVALUEStruct +{ + BYTE dummy; + DWORD dwType; + DWORD dwOperStatus; + DWORD dwNameLength; + WCHAR szName[1]; +}VALUEStruct; + +/* globals */ +extern HINSTANCE netshell_hInstance; +extern const GUID CLSID_NetworkConnections; +extern const GUID GUID_DEVCLASS_NET; + + +/* shfldr_netconnect.c */ +HRESULT WINAPI ISF_NetConnect_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); + +/* enumlist.c */ +IEnumIDList * IEnumIDList_Constructor(void); +LPITEMIDLIST _ILCreateNetConnect(); +LPITEMIDLIST ILCreateNetConnectItem(MIB_IFROW * pRow, LPWSTR szName, LPWSTR szAdapterName); +BOOL _ILIsNetConnect (LPCITEMIDLIST pidl); +BOOL AddToEnumList(IEnumIDList * iface, LPITEMIDLIST pidl); +VALUEStruct * _ILGetValueStruct(LPCITEMIDLIST pidl); + +/* classfactory.c */ +IClassFactory * IClassFactory_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst); + +#endif diff --git a/reactos/dll/win32/netshell/res/netshell.ico b/reactos/dll/win32/netshell/res/netshell.ico new file mode 100644 index 00000000000..cf3a1413d1d Binary files /dev/null and b/reactos/dll/win32/netshell/res/netshell.ico differ diff --git a/reactos/dll/win32/netshell/resource.h b/reactos/dll/win32/netshell/resource.h new file mode 100644 index 00000000000..79181a9a88e --- /dev/null +++ b/reactos/dll/win32/netshell/resource.h @@ -0,0 +1,31 @@ + +/* icons */ + +#define IDI_SHELL_NETWORK_FOLDER 100 + + +/* dialogs */ + + + + + +/* dialog controls */ + + +/* resource constants */ + +#define IDS_NETWORKCONNECTION 10000 +#define IDS_SHV_COLUMN_NAME 10001 +#define IDS_SHV_COLUMN_TYPE 10002 +#define IDS_SHV_COLUMN_STATE 10003 +#define IDS_SHV_COLUMN_DEVNAME 10004 +#define IDS_SHV_COLUMN_PHONE 10005 +#define IDS_SHV_COLUMN_OWNER 10006 +#define IDS_TYPE_ETHERNET 10007 +#define IDS_STATUS_NON_OPERATIONAL 10008 +#define IDS_STATUS_UNREACHABLE 10009 +#define IDS_STATUS_DISCONNECTED 10010 +#define IDS_STATUS_CONNECTING 10011 +#define IDS_STATUS_CONNECTED 10012 +#define IDS_STATUS_OPERATIONAL 10013 diff --git a/reactos/dll/win32/netshell/shfldr_netconnect.c b/reactos/dll/win32/netshell/shfldr_netconnect.c new file mode 100644 index 00000000000..6b9e8a1fb0d --- /dev/null +++ b/reactos/dll/win32/netshell/shfldr_netconnect.c @@ -0,0 +1,905 @@ +/* + * Network Connections Shell Folder + * + * Copyright 2008 Johannes Anderwald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +WINE_DEFAULT_DEBUG_CHANNEL (shell); + +/*********************************************************************** +* IShellFolder implementation +*/ + +typedef struct { + const IShellFolder2Vtbl *lpVtbl; + LONG ref; + const IContextMenu2Vtbl *lpVtblContextMenu; + const IPersistFolder2Vtbl *lpVtblPersistFolder2; + + /* both paths are parsible from the desktop */ + LPITEMIDLIST pidlRoot; /* absolute pidl */ + LPCITEMIDLIST apidl; /* currently focused font item */ +} IGenericSFImpl, *LPIGenericSFImpl; + + +static const shvheader NetConnectSFHeader[] = { + {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20}, + {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 8}, + {IDS_SHV_COLUMN_STATE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, + {IDS_SHV_COLUMN_DEVNAME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12}, + {IDS_SHV_COLUMN_PHONE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, + {IDS_SHV_COLUMN_OWNER, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5} +}; + +#define NETCONNECTSHELLVIEWCOLUMNS 6 + +#define COLUMN_NAME 0 +#define COLUMN_TYPE 1 +#define COLUMN_STATUS 2 +#define COLUMN_DEVNAME 3 +#define COLUMN_PHONE 4 +#define COLUMN_OWNER 5 + +static LPIGenericSFImpl __inline impl_from_IContextMenu2(IContextMenu2 *iface) +{ + return (LPIGenericSFImpl)((char *)iface - FIELD_OFFSET(IGenericSFImpl, lpVtblContextMenu)); +} + +static LPIGenericSFImpl __inline impl_from_IPersistFolder2(IPersistFolder2 *iface) +{ + return (LPIGenericSFImpl)((char *)iface - FIELD_OFFSET(IGenericSFImpl, lpVtblPersistFolder2)); +} + + + +/************************************************************************** + * ISF_NetConnect_fnQueryInterface + * + * NOTE + * supports not IPersist/IPersistFolder + */ +static HRESULT WINAPI ISF_NetConnect_fnQueryInterface (IShellFolder2 *iface, REFIID riid, LPVOID *ppvObj) +{ + IGenericSFImpl *This = (IGenericSFImpl *)iface; + + *ppvObj = NULL; + + if (IsEqualIID (riid, &IID_IUnknown) || + IsEqualIID (riid, &IID_IShellFolder) || + IsEqualIID (riid, &IID_IShellFolder2)) + { + *ppvObj = This; + } + else if (IsEqualIID (riid, &IID_IPersistFolder) || + IsEqualIID (riid, &IID_IPersistFolder2)) + { + *ppvObj = (LPVOID *)&This->lpVtblPersistFolder2; + } + if (*ppvObj) + { + IUnknown_AddRef ((IUnknown *) (*ppvObj)); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI ISF_NetConnect_fnAddRef (IShellFolder2 * iface) +{ + IGenericSFImpl *This = (IGenericSFImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +static ULONG WINAPI ISF_NetConnect_fnRelease (IShellFolder2 * iface) +{ + IGenericSFImpl *This = (IGenericSFImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + + if (!refCount) + { + SHFree (This->pidlRoot); + HeapFree (GetProcessHeap(), 0, This); + } + return refCount; +} + +/************************************************************************** +* ISF_NetConnect_fnParseDisplayName +*/ +static HRESULT WINAPI ISF_NetConnect_fnParseDisplayName (IShellFolder2 * iface, + HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName, + DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + HRESULT hr = E_UNEXPECTED; + + *ppidl = 0; + if (pchEaten) + *pchEaten = 0; /* strange but like the original */ + + return hr; +} + +/************************************************************************** + * CreateNetConnectEnumListss() + */ +static BOOL CreateNetConnectEnumList(IEnumIDList *list, DWORD dwFlags) +{ + DWORD dwSize, dwResult, dwIndex; + MIB_IFTABLE *pIfTable; + MIB_IFROW IfEntry; + IP_ADAPTER_INFO * pAdapterInfo, *pCurrentAdapter; + HDEVINFO hInfo; + SP_DEVINFO_DATA DevInfo; + HKEY hSubKey; + WCHAR szNetCfg[50]; + WCHAR szAdapterNetCfg[50]; + LPITEMIDLIST pidl; + WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\"; + WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; + + /* get the IfTable */ + dwSize = 0; + if (GetIfTable(NULL, &dwSize, TRUE) != ERROR_INSUFFICIENT_BUFFER) + return FALSE; + + pIfTable = (PMIB_IFTABLE)HeapAlloc(GetProcessHeap(), 0, dwSize); + if (!pIfTable) + return FALSE; + + dwResult = GetIfTable(pIfTable, &dwSize, TRUE); + if (dwResult != NO_ERROR) + { + HeapFree(GetProcessHeap(), 0, pIfTable); + return FALSE; + } + + dwSize = 0; + dwResult = GetAdaptersInfo(NULL, &dwSize); + if (dwResult!= ERROR_BUFFER_OVERFLOW) + { + HeapFree(GetProcessHeap(), 0, pIfTable); + return FALSE; + } + + pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, dwSize); + if (!pAdapterInfo) + { + HeapFree(GetProcessHeap(), 0, pIfTable); + return FALSE; + } + + if (GetAdaptersInfo(pAdapterInfo, &dwSize) != NO_ERROR) + { + HeapFree(GetProcessHeap(), 0, pIfTable); + HeapFree(GetProcessHeap(), 0, pAdapterInfo); + return FALSE; + } + + + hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT ); + if (!hInfo) + { + HeapFree(GetProcessHeap(), 0, pIfTable); + HeapFree(GetProcessHeap(), 0, pAdapterInfo); + return FALSE; + } + + dwIndex = 0; + do + { + ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA)); + DevInfo.cbSize = sizeof(DevInfo); + if (SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo)) + { + if (SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize)) + { + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) + { + dwSize = sizeof(szNetCfg); + dwResult = RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize); + if (dwResult == ERROR_SUCCESS) + { + pCurrentAdapter = pAdapterInfo; + while(pCurrentAdapter) + { + szAdapterNetCfg[0] = L'\0'; + if (MultiByteToWideChar(CP_ACP, 0, pCurrentAdapter->AdapterName, -1, szAdapterNetCfg, sizeof(szAdapterNetCfg)/sizeof(szAdapterNetCfg[0]))) + { + szAdapterNetCfg[(sizeof(szAdapterNetCfg)/sizeof(WCHAR))-1] = L'\0'; + } + if (!wcsicmp(szAdapterNetCfg, szNetCfg)) + { + ZeroMemory(&IfEntry, sizeof(IfEntry)); + IfEntry.dwIndex = pCurrentAdapter->Index; + dwResult = GetIfEntry(&IfEntry); + if (dwResult == NO_ERROR) + { + if (IfEntry.dwType == IF_TYPE_ETHERNET_CSMACD || IfEntry.dwType == IF_TYPE_IEEE80211) + { + wcscpy(&szName[80], szNetCfg); + wcscpy(&szName[118], L"\\Connection"); + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) + { + dwSize = sizeof(szAdapterNetCfg); + if (RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) != ERROR_SUCCESS) + { + if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szAdapterNetCfg, sizeof(szAdapterNetCfg)/sizeof(WCHAR), &dwSize)) + { + szDetail[0] = 0; + } + } + RegCloseKey(hSubKey); + } + szNetCfg[0] = 0; + SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)szNetCfg, sizeof(szNetCfg)/sizeof(WCHAR), &dwSize); + pidl = ILCreateNetConnectItem(&IfEntry, szAdapterNetCfg, szNetCfg); + if (pidl) + { + AddToEnumList(list, pidl); + } + } + } + break; + } + pCurrentAdapter = pCurrentAdapter->Next; + } + } + } + } + }else if (GetLastError() == ERROR_NO_MORE_ITEMS) + { + break; + } + }while(TRUE); + + HeapFree(GetProcessHeap(), 0, pAdapterInfo); + HeapFree(GetProcessHeap(), 0, pIfTable); + SetupDiDestroyDeviceInfoList(hInfo); + + return FALSE; + +} + +/************************************************************************** +* ISF_NetConnect_fnEnumObjects +*/ +static HRESULT WINAPI ISF_NetConnect_fnEnumObjects (IShellFolder2 * iface, + HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + *ppEnumIDList = IEnumIDList_Constructor(); + if(*ppEnumIDList) + CreateNetConnectEnumList(*ppEnumIDList, dwFlags); + + + return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY; +} + +/************************************************************************** +* ISF_NetConnect_fnBindToObject +*/ +static HRESULT WINAPI ISF_NetConnect_fnBindToObject (IShellFolder2 * iface, + LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + return E_NOTIMPL; +} + +/************************************************************************** +* ISF_NetConnect_fnBindToStorage +*/ +static HRESULT WINAPI ISF_NetConnect_fnBindToStorage (IShellFolder2 * iface, + LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + + *ppvOut = NULL; + return E_NOTIMPL; +} + +/************************************************************************** +* ISF_NetConnect_fnCompareIDs +*/ + +static HRESULT WINAPI ISF_NetConnect_fnCompareIDs (IShellFolder2 * iface, + LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + + + return E_NOTIMPL; +} + +/************************************************************************** +* ISF_NetConnect_fnCreateViewObject +*/ +static HRESULT WINAPI ISF_NetConnect_fnCreateViewObject (IShellFolder2 * iface, + HWND hwndOwner, REFIID riid, LPVOID * ppvOut) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + IShellView* pShellView; + CSFV cvf; + HRESULT hr = E_NOINTERFACE; + + if (!ppvOut) + return hr; + + *ppvOut = NULL; + + if (IsEqualIID (riid, &IID_IShellView)) + { + ZeroMemory(&cvf, sizeof(cvf)); + cvf.cbSize = sizeof(cvf); + cvf.pshf = (IShellFolder*)iface; + + hr = SHCreateShellFolderViewEx(&cvf, &pShellView); + if (SUCCEEDED(hr)) + { + hr = IShellView_QueryInterface (pShellView, riid, ppvOut); + IShellView_Release (pShellView); + } + } + + return hr; +} + +/************************************************************************** +* ISF_NetConnect_fnGetAttributesOf +*/ +static HRESULT WINAPI ISF_NetConnect_fnGetAttributesOf (IShellFolder2 * iface, + UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + HRESULT hr = S_OK; + static const DWORD dwNetConnectAttributes = SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | + SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE; + + + if (!rgfInOut) + return E_INVALIDARG; + + if (cidl && !apidl) + return E_INVALIDARG; + + if (*rgfInOut == 0) + *rgfInOut = ~0; + + if(cidl == 0) + *rgfInOut = dwNetConnectAttributes; + + /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ + *rgfInOut &= ~SFGAO_VALIDATE; + + return hr; +} + +/************************************************************************** +* ISF_NetConnect_fnGetUIObjectOf +* +* PARAMETERS +* hwndOwner [in] Parent window for any output +* cidl [in] array size +* apidl [in] simple pidl array +* riid [in] Requested Interface +* prgfInOut [ ] reserved +* ppvObject [out] Resulting Interface +* +*/ +static HRESULT WINAPI ISF_NetConnect_fnGetUIObjectOf (IShellFolder2 * iface, + HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, + UINT * prgfInOut, LPVOID * ppvOut) +{ + IGenericSFImpl *This = (IGenericSFImpl *)iface; + + IUnknown *pObj = NULL; + HRESULT hr = E_INVALIDARG; + + if (!ppvOut) + return hr; + + *ppvOut = NULL; + + if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) + { + pObj = (IUnknown*)(&This->lpVtblContextMenu); + This->apidl = apidl[0]; + IUnknown_AddRef(pObj); + hr = S_OK; + } + else + hr = E_NOINTERFACE; + + if (SUCCEEDED(hr) && !pObj) + hr = E_OUTOFMEMORY; + + *ppvOut = pObj; + return hr; +} + +/************************************************************************** +* ISF_NetConnect_fnGetDisplayNameOf +* +*/ +static HRESULT WINAPI ISF_NetConnect_fnGetDisplayNameOf (IShellFolder2 * iface, + LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet) +{ + LPWSTR pszName; + HRESULT hr = E_FAIL; + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + if (!strRet) + return E_INVALIDARG; + + pszName = CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR)); + if (!pszName) + return E_OUTOFMEMORY; + + if (_ILIsNetConnect (pidl)) + { + if (LoadStringW(netshell_hInstance, IDS_NETWORKCONNECTION, pszName, MAX_PATH)) + { + pszName[MAX_PATH-1] = L'\0'; + hr = S_OK; + } + } + else + { + VALUEStruct * val = _ILGetValueStruct(pidl); + if (val) + { + wcscpy(pszName, val->szName); + hr = S_OK; + } + + } + + if (SUCCEEDED(hr)) + { + strRet->uType = STRRET_WSTR; + strRet->u.pOleStr = pszName; + } + else + { + CoTaskMemFree(pszName); + } + + return hr; +} + +/************************************************************************** +* ISF_NetConnect_fnSetNameOf +* Changes the name of a file object or subfolder, possibly changing its item +* identifier in the process. +* +* PARAMETERS +* hwndOwner [in] Owner window for output +* pidl [in] simple pidl of item to change +* lpszName [in] the items new display name +* dwFlags [in] SHGNO formatting flags +* ppidlOut [out] simple pidl returned +*/ +static HRESULT WINAPI ISF_NetConnect_fnSetNameOf (IShellFolder2 * iface, + HWND hwndOwner, LPCITEMIDLIST pidl, /*simple pidl */ + LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + return E_NOTIMPL; +} + +static HRESULT WINAPI ISF_NetConnect_fnGetDefaultSearchGUID ( + IShellFolder2 * iface, GUID * pguid) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + return E_NOTIMPL; +} + +static HRESULT WINAPI ISF_NetConnect_fnEnumSearches (IShellFolder2 * iface, + IEnumExtraSearch ** ppenum) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + return E_NOTIMPL; +} + +static HRESULT WINAPI ISF_NetConnect_fnGetDefaultColumn (IShellFolder2 * iface, + DWORD dwRes, ULONG * pSort, ULONG * pDisplay) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + if (pSort) + *pSort = 0; + if (pDisplay) + *pDisplay = 0; + + return S_OK; +} + +static HRESULT WINAPI ISF_NetConnect_fnGetDefaultColumnState ( + IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + if (!pcsFlags || iColumn >= NETCONNECTSHELLVIEWCOLUMNS) + return E_INVALIDARG; + *pcsFlags = NetConnectSFHeader[iColumn].pcsFlags; + return S_OK; +} + +static HRESULT WINAPI ISF_NetConnect_fnGetDetailsEx (IShellFolder2 * iface, + LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + return E_NOTIMPL; +} + +static HRESULT WINAPI ISF_NetConnect_fnGetDetailsOf (IShellFolder2 * iface, + LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + WCHAR buffer[MAX_PATH] = {0}; + HRESULT hr = E_FAIL; + VALUEStruct * val; + + if (iColumn >= NETCONNECTSHELLVIEWCOLUMNS) + return E_FAIL; + + psd->fmt = NetConnectSFHeader[iColumn].fmt; + psd->cxChar = NetConnectSFHeader[iColumn].cxChar; + if (pidl == NULL) + { + psd->str.uType = STRRET_WSTR; + if (LoadStringW(netshell_hInstance, NetConnectSFHeader[iColumn].colnameid, buffer, MAX_PATH)) + hr = SHStrDupW(buffer, &psd->str.u.pOleStr); + + return hr; + } + + if (iColumn == COLUMN_NAME) + { + psd->str.uType = STRRET_WSTR; + return IShellFolder2_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL, &psd->str); + } + + val = _ILGetValueStruct(pidl); + if (!val) + return E_FAIL; + + switch(iColumn) + { + case COLUMN_TYPE: + if (val->dwType == IF_TYPE_ETHERNET_CSMACD || val->dwType == IF_TYPE_IEEE80211) + { + if (LoadStringW(netshell_hInstance, IDS_TYPE_ETHERNET, buffer, MAX_PATH)) + { + psd->str.uType = STRRET_WSTR; + hr = SHStrDupW(buffer, &psd->str.u.pOleStr); + } + } + break; + case COLUMN_STATUS: + buffer[0] = L'\0'; + if (val->dwOperStatus == MIB_IF_OPER_STATUS_NON_OPERATIONAL) + LoadStringW(netshell_hInstance, IDS_STATUS_NON_OPERATIONAL, buffer, MAX_PATH); + else if (val->dwOperStatus == MIB_IF_OPER_STATUS_UNREACHABLE) + LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, buffer, MAX_PATH); + else if (val->dwOperStatus == MIB_IF_OPER_STATUS_DISCONNECTED) + LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, buffer, MAX_PATH); + else if (val->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTING) + LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, buffer, MAX_PATH); + else if (val->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED) + LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, buffer, MAX_PATH); + else if (val->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) + LoadStringW(netshell_hInstance, IDS_STATUS_OPERATIONAL, buffer, MAX_PATH); + + if (buffer[0]) + { + buffer[MAX_PATH-1] = L'\0'; + psd->str.uType = STRRET_WSTR; + hr = SHStrDupW(buffer, &psd->str.u.pOleStr); + } + break; + case COLUMN_DEVNAME: + wcscpy(buffer, val->szName + val->dwNameLength); + buffer[MAX_PATH-1] = L'\0'; + psd->str.uType = STRRET_WSTR; + hr = SHStrDupW(buffer, &psd->str.u.pOleStr); + break; + case COLUMN_PHONE: + case COLUMN_OWNER: + psd->str.u.cStr[0] = '\0'; + psd->str.uType = STRRET_CSTR; + break; + } + + return hr; +} + +static HRESULT WINAPI ISF_NetConnect_fnMapColumnToSCID (IShellFolder2 * iface, + UINT column, SHCOLUMNID * pscid) +{ + //IGenericSFImpl *This = (IGenericSFImpl *)iface; + + return E_NOTIMPL; +} + +static const IShellFolder2Vtbl vt_ShellFolder2 = { + ISF_NetConnect_fnQueryInterface, + ISF_NetConnect_fnAddRef, + ISF_NetConnect_fnRelease, + ISF_NetConnect_fnParseDisplayName, + ISF_NetConnect_fnEnumObjects, + ISF_NetConnect_fnBindToObject, + ISF_NetConnect_fnBindToStorage, + ISF_NetConnect_fnCompareIDs, + ISF_NetConnect_fnCreateViewObject, + ISF_NetConnect_fnGetAttributesOf, + ISF_NetConnect_fnGetUIObjectOf, + ISF_NetConnect_fnGetDisplayNameOf, + ISF_NetConnect_fnSetNameOf, + /* ShellFolder2 */ + ISF_NetConnect_fnGetDefaultSearchGUID, + ISF_NetConnect_fnEnumSearches, + ISF_NetConnect_fnGetDefaultColumn, + ISF_NetConnect_fnGetDefaultColumnState, + ISF_NetConnect_fnGetDetailsEx, + ISF_NetConnect_fnGetDetailsOf, + ISF_NetConnect_fnMapColumnToSCID +}; + +/************************************************************************** +* IContextMenu2 Implementation +*/ + +/************************************************************************ + * ISF_NetConnect_IContextMenu_QueryInterface + */ +static HRESULT WINAPI ISF_NetConnect_IContextMenu2_QueryInterface(IContextMenu2 * iface, REFIID iid, LPVOID * ppvObject) +{ + IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + return IShellFolder2_QueryInterface((IShellFolder2*)This, iid, ppvObject); +} + +/************************************************************************ + * ISF_NetConnect_IContextMenu_AddRef + */ +static ULONG WINAPI ISF_NetConnect_IContextMenu2_AddRef(IContextMenu2 * iface) +{ + IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + return IShellFolder2_AddRef((IShellFolder2*)This); +} + +/************************************************************************ + * ISF_NetConnect_IContextMenu_Release + */ +static ULONG WINAPI ISF_NetConnect_IContextMenu2_Release(IContextMenu2 * iface) +{ + IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + return IShellFolder2_Release((IShellFolder2*)This); +} + +/************************************************************************** +* ISF_NetConnect_IContextMenu_QueryContextMenu() +*/ +static HRESULT WINAPI ISF_NetConnect_IContextMenu2_QueryContextMenu( + IContextMenu2 *iface, + HMENU hMenu, + UINT indexMenu, + UINT idCmdFirst, + UINT idCmdLast, + UINT uFlags) +{ + int Count = 1; + //IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, Count); +} + + +/************************************************************************** +* ISF_NetConnect_IContextMenu_InvokeCommand() +*/ +static HRESULT WINAPI ISF_NetConnect_IContextMenu2_InvokeCommand( + IContextMenu2 *iface, + LPCMINVOKECOMMANDINFO lpcmi) +{ + //IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + return S_OK; +} + +/************************************************************************** + * ISF_NetConnect_IContextMenu_GetCommandString() + * + */ +static HRESULT WINAPI ISF_NetConnect_IContextMenu2_GetCommandString( + IContextMenu2 *iface, + UINT_PTR idCommand, + UINT uFlags, + UINT* lpReserved, + LPSTR lpszName, + UINT uMaxNameLen) +{ + //IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + return E_FAIL; +} + + + +/************************************************************************** +* ISF_NetConnect_IContextMenu_HandleMenuMsg() +*/ +static HRESULT WINAPI ISF_NetConnect_IContextMenu2_HandleMenuMsg( + IContextMenu2 *iface, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + //IGenericSFImpl * This = impl_from_IContextMenu2(iface); + + + return E_NOTIMPL; +} + +static const IContextMenu2Vtbl vt_ContextMenu2 = +{ + ISF_NetConnect_IContextMenu2_QueryInterface, + ISF_NetConnect_IContextMenu2_AddRef, + ISF_NetConnect_IContextMenu2_Release, + ISF_NetConnect_IContextMenu2_QueryContextMenu, + ISF_NetConnect_IContextMenu2_InvokeCommand, + ISF_NetConnect_IContextMenu2_GetCommandString, + ISF_NetConnect_IContextMenu2_HandleMenuMsg +}; + +/************************************************************************ + * ISF_NetConnect_PersistFolder2_QueryInterface + */ +static HRESULT WINAPI ISF_NetConnect_PersistFolder2_QueryInterface (IPersistFolder2 * iface, + REFIID iid, LPVOID * ppvObj) +{ + IGenericSFImpl * This = impl_from_IPersistFolder2(iface); + + return IShellFolder2_QueryInterface ((IShellFolder2*)This, iid, ppvObj); +} + +/************************************************************************ + * ISF_NetConnect_PersistFolder2_AddRef + */ +static ULONG WINAPI ISF_NetConnect_PersistFolder2_AddRef (IPersistFolder2 * iface) +{ + IGenericSFImpl * This = impl_from_IPersistFolder2(iface); + + return IShellFolder2_AddRef((IShellFolder2*)This); +} + +/************************************************************************ + * ISF_NetConnect_PersistFolder2_Release + */ +static ULONG WINAPI ISF_NetConnect_PersistFolder2_Release (IPersistFolder2 * iface) +{ + IGenericSFImpl * This = impl_from_IPersistFolder2(iface); + + return IShellFolder2_Release((IShellFolder2*)This); +} + +/************************************************************************ + * ISF_NetConnect_PersistFolder2_GetClassID + */ +static HRESULT WINAPI ISF_NetConnect_PersistFolder2_GetClassID ( + IPersistFolder2 * iface, CLSID * lpClassId) +{ + //IGenericSFImpl * This = impl_from_IPersistFolder2(iface); + + if (!lpClassId) + return E_POINTER; + + *lpClassId = CLSID_NetworkConnections; + + return S_OK; +} + +/************************************************************************ + * ISF_NetConnect_PersistFolder2_Initialize + * + * NOTES: it makes no sense to change the pidl + */ +static HRESULT WINAPI ISF_NetConnect_PersistFolder2_Initialize ( + IPersistFolder2 * iface, LPCITEMIDLIST pidl) +{ + IGenericSFImpl * This = impl_from_IPersistFolder2(iface); + + SHFree(This->pidlRoot); + This->pidlRoot = ILClone(pidl); + + return S_OK; +} + +/************************************************************************** + * ISF_NetConnect_PersistFolder2_GetCurFolder + */ +static HRESULT WINAPI ISF_NetConnect_PersistFolder2_GetCurFolder ( + IPersistFolder2 * iface, LPITEMIDLIST * pidl) +{ + IGenericSFImpl * This = impl_from_IPersistFolder2(iface); + + + if (!pidl) + return E_POINTER; + + *pidl = ILClone (This->pidlRoot); + + return S_OK; +} + +static const IPersistFolder2Vtbl vt_PersistFolder2 = +{ + ISF_NetConnect_PersistFolder2_QueryInterface, + ISF_NetConnect_PersistFolder2_AddRef, + ISF_NetConnect_PersistFolder2_Release, + ISF_NetConnect_PersistFolder2_GetClassID, + ISF_NetConnect_PersistFolder2_Initialize, + ISF_NetConnect_PersistFolder2_GetCurFolder +}; + +/************************************************************************** +* ISF_NetConnect_Constructor +*/ +HRESULT WINAPI ISF_NetConnect_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) +{ + IGenericSFImpl *sf; + + if (!ppv) + return E_POINTER; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + sf = (IGenericSFImpl *) HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (IGenericSFImpl)); + if (!sf) + return E_OUTOFMEMORY; + + sf->ref = 1; + sf->lpVtbl = &vt_ShellFolder2; + sf->lpVtblPersistFolder2 = &vt_PersistFolder2; + sf->lpVtblContextMenu = &vt_ContextMenu2; + sf->pidlRoot = _ILCreateNetConnect(); /* my qualified pidl */ + + if (!SUCCEEDED (IShellFolder2_QueryInterface ((IShellFolder2*)sf, riid, ppv))) + { + IShellFolder2_Release((IShellFolder2*)sf); + return E_NOINTERFACE; + } + + return S_OK; +} diff --git a/reactos/dll/win32/win32.rbuild b/reactos/dll/win32/win32.rbuild index 27242319771..5be582cddd6 100644 --- a/reactos/dll/win32/win32.rbuild +++ b/reactos/dll/win32/win32.rbuild @@ -196,6 +196,9 @@ + + +