diff --git a/reactos/dll/win32/netcfgx/classfactory.c b/reactos/dll/win32/netcfgx/classfactory.c index d03c5f340cc..0ef66c5497e 100644 --- a/reactos/dll/win32/netcfgx/classfactory.c +++ b/reactos/dll/win32/netcfgx/classfactory.c @@ -1,4 +1,4 @@ -#include +#include "precomp.h" typedef struct { diff --git a/reactos/dll/win32/netcfgx/inetcfgcomp_iface.c b/reactos/dll/win32/netcfgx/inetcfgcomp_iface.c new file mode 100644 index 00000000000..8ef1a9ec64e --- /dev/null +++ b/reactos/dll/win32/netcfgx/inetcfgcomp_iface.c @@ -0,0 +1,516 @@ +#include "precomp.h" +#include + +typedef struct +{ + const INetCfgComponent * lpVtbl; + LONG ref; + NetCfgComponentItem * pItem; +}INetCfgComponentImpl; + +typedef struct +{ + const IEnumNetCfgComponent * lpVtbl; + LONG ref; + NetCfgComponentItem * pCurrent; + NetCfgComponentItem * pHead; +}IEnumNetCfgComponentImpl; + + + +HRESULT +STDCALL +INetCfgComponent_fnQueryInterface( + INetCfgComponent * iface, + REFIID iid, + LPVOID * ppvObj) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + *ppvObj = NULL; + + if (IsEqualIID (iid, &IID_IUnknown) || + IsEqualIID (iid, &IID_INetCfgComponent)) + { + *ppvObj = This; + INetCfg_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + + +ULONG +STDCALL +INetCfgComponent_fnAddRef( + INetCfgComponent * iface) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +ULONG +STDCALL +INetCfgComponent_fnRelease( + INetCfgComponent * iface) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + return refCount; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetDisplayName( + INetCfgComponent * iface, + LPWSTR * ppszwDisplayName) +{ + LPWSTR szName; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || ppszwDisplayName == NULL) + return E_POINTER; + + szName = CoTaskMemAlloc((wcslen(This->pItem->szDisplayName)+1) * sizeof(WCHAR)); + if (!szName) + return E_OUTOFMEMORY; + + wcscpy(szName, This->pItem->szDisplayName); + *ppszwDisplayName = szName; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnSetDisplayName( + INetCfgComponent * iface, + LPCWSTR ppszwDisplayName) +{ + LPWSTR szName; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || ppszwDisplayName == NULL) + return E_POINTER; + + /* setting name is only supported for network cards */ + if (!IsEqualGUID(&This->pItem->ClassGUID, &GUID_DEVCLASS_NET)) + return E_NOTIMPL; + + /// FIXME + /// check for invalid characters + /// check for write lock + + szName = CoTaskMemAlloc((wcslen(ppszwDisplayName)+1) * sizeof(WCHAR)); + if (!szName) + return E_OUTOFMEMORY; + + wcscpy(szName, ppszwDisplayName); + CoTaskMemFree(This->pItem->szDisplayName); + This->pItem->szDisplayName = szName; + This->pItem->bChanged = TRUE; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetHelpText( + INetCfgComponent * iface, + LPWSTR * ppszwHelpText) +{ + LPWSTR szHelp; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || ppszwHelpText == NULL) + return E_POINTER; + + szHelp = CoTaskMemAlloc((wcslen(This->pItem->szHelpText)+1) * sizeof(WCHAR)); + if (!szHelp) + return E_OUTOFMEMORY; + + wcscpy(szHelp, This->pItem->szHelpText); + *ppszwHelpText = szHelp; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetId( + INetCfgComponent * iface, + LPWSTR * ppszwId) +{ + LPWSTR szId; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || ppszwId == NULL) + return E_POINTER; + + szId = CoTaskMemAlloc((wcslen(This->pItem->szId)+1) * sizeof(WCHAR)); + if (!szId) + return E_OUTOFMEMORY; + + wcscpy(szId, This->pItem->szId); + *ppszwId = szId; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetCharacteristics( + INetCfgComponent * iface, + DWORD * pdwCharacteristics) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || pdwCharacteristics == NULL) + return E_POINTER; + + *pdwCharacteristics = This->pItem->dwCharacteristics; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetInstanceGuid( + INetCfgComponent * iface, + GUID * pGuid) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || pGuid == NULL) + return E_POINTER; + + CopyMemory(pGuid, &This->pItem->InstanceId, sizeof(GUID)); + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetPnpDevNodeId( + INetCfgComponent * iface, + LPWSTR * ppszwDevNodeId) +{ + LPWSTR szNode; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || ppszwDevNodeId == NULL) + return E_POINTER; + + if (!IsEqualGUID(&GUID_DEVCLASS_NET, &This->pItem->ClassGUID)) + return E_NOTIMPL; + + szNode = CoTaskMemAlloc((wcslen(This->pItem->szNodeId)+1) * sizeof(WCHAR)); + if (!szNode) + return E_OUTOFMEMORY; + + wcscpy(szNode, This->pItem->szNodeId); + *ppszwDevNodeId = szNode; + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetClassGuid( + INetCfgComponent * iface, + GUID * pGuid) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || pGuid == NULL) + return E_POINTER; + + CopyMemory(pGuid, &This->pItem->ClassGUID, sizeof(GUID)); + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetBindName( + INetCfgComponent * iface, + LPWSTR * ppszwBindName) +{ + LPWSTR szBind; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || ppszwBindName == NULL) + return E_POINTER; + + szBind = CoTaskMemAlloc((wcslen(This->pItem->szBindName)+1) * sizeof(WCHAR)); + if (!szBind) + return E_OUTOFMEMORY; + + wcscpy(szBind, This->pItem->szBindName); + *ppszwBindName = szBind; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnGetDeviceStatus( + INetCfgComponent * iface, + ULONG * pStatus) +{ + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || pStatus == NULL) + return E_POINTER; + + if (!IsEqualGUID(&GUID_DEVCLASS_NET, &This->pItem->ClassGUID)) + return E_UNEXPECTED; + + *pStatus = This->pItem->Status; + + return S_OK; +} + +HRESULT +STDCALL +INetCfgComponent_fnOpenParamKey( + INetCfgComponent * iface, + HKEY * phkey) +{ + WCHAR szBuffer[200] = L"SYSTEM\\CurrentControlSet\\Services\\"; + INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface; + + if (This == NULL || phkey == NULL) + return E_POINTER; + + wcscat(szBuffer, This->pItem->szBindName); + wcscat(szBuffer, L"\\Parameters"); + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ | KEY_WRITE, phkey) == ERROR_SUCCESS) + return S_OK; + else + return E_FAIL; +} + +HRESULT +STDCALL +INetCfgComponent_fnRaisePropertyUi( + INetCfgComponent * iface, + IN HWND hwndParent, + IN DWORD dwFlags, + IN IUnknown *pUnk) +{ + + return E_NOTIMPL; +} +static const INetCfgComponentVtbl vt_NetCfgComponent = +{ + INetCfgComponent_fnQueryInterface, + INetCfgComponent_fnAddRef, + INetCfgComponent_fnRelease, + INetCfgComponent_fnGetDisplayName, + INetCfgComponent_fnSetDisplayName, + INetCfgComponent_fnGetHelpText, + INetCfgComponent_fnGetId, + INetCfgComponent_fnGetCharacteristics, + INetCfgComponent_fnGetInstanceGuid, + INetCfgComponent_fnGetPnpDevNodeId, + INetCfgComponent_fnGetClassGuid, + INetCfgComponent_fnGetBindName, + INetCfgComponent_fnGetDeviceStatus, + INetCfgComponent_fnOpenParamKey, + INetCfgComponent_fnRaisePropertyUi +}; + +HRESULT +STDCALL +INetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem) +{ + INetCfgComponentImpl *This; + + if (!ppv) + return E_POINTER; + + This = (INetCfgComponentImpl *) CoTaskMemAlloc(sizeof (INetCfgComponentImpl)); + if (!This) + return E_OUTOFMEMORY; + + This->ref = 1; + This->lpVtbl = (const INetCfgComponent*)&vt_NetCfgComponent; + This->pItem = pItem; + + if (!SUCCEEDED (INetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv))) + { + INetCfgComponent_Release((INetCfg*)This); + return E_NOINTERFACE; + } + + INetCfgComponent_Release((INetCfgComponent*)This); + return S_OK; + + + return S_OK; +} + + +/*************************************************************** + * IEnumNetCfgComponent + */ + +HRESULT +STDCALL +IEnumNetCfgComponent_fnQueryInterface( + IEnumNetCfgComponent * iface, + REFIID iid, + LPVOID * ppvObj) +{ + IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface; + *ppvObj = NULL; + + if (IsEqualIID (iid, &IID_IUnknown) || + IsEqualIID (iid, &IID_IEnumNetCfgComponent)) + { + *ppvObj = This; + INetCfg_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + + +ULONG +STDCALL +IEnumNetCfgComponent_fnAddRef( + IEnumNetCfgComponent * iface) +{ + IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +ULONG +STDCALL +IEnumNetCfgComponent_fnRelease( + IEnumNetCfgComponent * iface) +{ + IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + return refCount; +} + +HRESULT +STDCALL +IEnumNetCfgComponent_fnNext( + IEnumNetCfgComponent * iface, + ULONG celt, + INetCfgComponent **rgelt, + ULONG *pceltFetched) +{ + HRESULT hr; + IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface; + + if (!iface || !rgelt) + return E_POINTER; + + if (celt != 1) + return E_INVALIDARG; + + if (!This->pCurrent) + return S_FALSE; + + hr = INetCfgComponent_Constructor (NULL, &IID_INetCfgComponent, (LPVOID*)rgelt, This->pCurrent); + if (SUCCEEDED(hr)) + { + This->pCurrent = This->pCurrent->pNext; + if (pceltFetched) + *pceltFetched = 1; + } + return hr; +} + +HRESULT +STDCALL +IEnumNetCfgComponent_fnSkip( + IEnumNetCfgComponent * iface, + ULONG celt) +{ + IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface; + + if (!This->pCurrent) + return S_FALSE; + + while(celt-- > 0 && This->pCurrent) + This->pCurrent = This->pCurrent->pNext; + + if (!celt) + return S_OK; + else + return S_FALSE; +} + +HRESULT +STDCALL +IEnumNetCfgComponent_fnReset( + IEnumNetCfgComponent * iface) +{ + IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface; + + This->pCurrent = This->pHead; + return S_OK; +} + +HRESULT +STDCALL +IEnumNetCfgComponent_fnClone( + IEnumNetCfgComponent * iface, + IEnumNetCfgComponent **ppenum) +{ + return E_NOTIMPL; +} + +static const IEnumNetCfgComponentVtbl vt_EnumNetCfgComponent = +{ + IEnumNetCfgComponent_fnQueryInterface, + IEnumNetCfgComponent_fnAddRef, + IEnumNetCfgComponent_fnRelease, + IEnumNetCfgComponent_fnNext, + IEnumNetCfgComponent_fnSkip, + IEnumNetCfgComponent_fnReset, + IEnumNetCfgComponent_fnClone +}; + +HRESULT +STDCALL +IEnumNetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem) +{ + IEnumNetCfgComponentImpl *This; + + if (!ppv) + return E_POINTER; + + This = (IEnumNetCfgComponentImpl *) CoTaskMemAlloc(sizeof (IEnumNetCfgComponentImpl)); + if (!This) + return E_OUTOFMEMORY; + + This->ref = 1; + This->lpVtbl = (const IEnumNetCfgComponent*)&vt_EnumNetCfgComponent; + This->pCurrent = pItem; + This->pHead = pItem; + + if (!SUCCEEDED (IEnumNetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv))) + { + IEnumNetCfgComponent_Release((INetCfg*)This); + return E_NOINTERFACE; + } + + IEnumNetCfgComponent_Release((IEnumNetCfgComponent*)This); + return S_OK; + + + return S_OK; +} + + diff --git a/reactos/dll/win32/netcfgx/netcfg_iface.c b/reactos/dll/win32/netcfgx/netcfg_iface.c new file mode 100644 index 00000000000..d5648046555 --- /dev/null +++ b/reactos/dll/win32/netcfgx/netcfg_iface.c @@ -0,0 +1,694 @@ +#include "precomp.h" +#include + +typedef struct +{ + const INetCfg * lpVtbl; + const INetCfgLock * lpVtblLock; + LONG ref; + BOOL bInitialized; + HANDLE hMutex; + NetCfgComponentItem *pNet; + NetCfgComponentItem * pService; + NetCfgComponentItem * pClient; + NetCfgComponentItem * pProtocol; +} INetCfgImpl, *LPINetCfgImpl; + +static LPINetCfgImpl __inline impl_from_INetCfgLock(INetCfgLock *iface) +{ + return (INetCfgImpl*)((char *)iface - FIELD_OFFSET(INetCfgImpl, lpVtblLock)); +} + + + +HRESULT +STDCALL +INetCfgLock_fnQueryInterface( + INetCfgLock * iface, + REFIID iid, + LPVOID * ppvObj) +{ + INetCfgImpl * This = impl_from_INetCfgLock(iface); + return INetCfg_QueryInterface((INetCfg*)This, iid, ppvObj); +} + + +ULONG +STDCALL +INetCfgLock_fnAddRef( + INetCfgLock * iface) +{ + INetCfgImpl * This = impl_from_INetCfgLock(iface); + + return INetCfg_AddRef((INetCfg*)This); +} + +ULONG +STDCALL +INetCfgLock_fnRelease( + INetCfgLock * iface) +{ + INetCfgImpl * This = impl_from_INetCfgLock(iface); + return INetCfg_Release((INetCfg*)This); +} + +HRESULT +STDCALL +INetCfgLock_fnAcquireWriteLock( + INetCfgLock * iface, + DWORD cmsTimeout, + LPCWSTR pszwClientDescription, + LPWSTR *ppszwClientDescription) +{ + DWORD dwResult; + HKEY hKey; + WCHAR szValue[100]; + INetCfgImpl * This = impl_from_INetCfgLock(iface); + + if (This->bInitialized) + return NETCFG_E_ALREADY_INITIALIZED; + + dwResult = WaitForSingleObject(This->hMutex, cmsTimeout); + if (dwResult == WAIT_TIMEOUT) + { + if (ppszwClientDescription) + { + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + dwResult = sizeof(szValue); + if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szValue, &dwResult) == ERROR_SUCCESS) + { + szValue[(sizeof(szValue)/sizeof(WCHAR))-1] = L'\0'; + *ppszwClientDescription = CoTaskMemAlloc((wcslen(szValue)+1) * sizeof(WCHAR)); + if (*ppszwClientDescription) + wcscpy(*ppszwClientDescription, szValue); + } + RegCloseKey(hKey); + } + } + return S_FALSE; + } + else if (dwResult == WAIT_OBJECT_0) + { + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) + { + RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)pszwClientDescription, (wcslen(pszwClientDescription)+1) * sizeof(WCHAR)); + RegCloseKey(hKey); + } + return S_OK; + } + + return E_FAIL; +} + +HRESULT +STDCALL +INetCfgLock_fnReleaseWriteLock( + INetCfgLock * iface) +{ + INetCfgImpl * This = impl_from_INetCfgLock(iface); + + if (This->bInitialized) + return NETCFG_E_ALREADY_INITIALIZED; + + + if (ReleaseMutex(This->hMutex)) + return S_OK; + else + return S_FALSE; +} + +HRESULT +STDCALL +INetCfgLock_fnIsWriteLocked( + INetCfgLock * iface, + LPWSTR *ppszwClientDescription) +{ + HKEY hKey; + WCHAR szValue[100]; + DWORD dwSize, dwType; + HRESULT hr; + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + return S_FALSE; + + dwSize = sizeof(szValue); + if (RegQueryValueExW(hKey, NULL, NULL, &dwType, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS && dwType == REG_SZ) + { + hr = S_OK; + szValue[(sizeof(szValue)/sizeof(WCHAR))-1] = L'\0'; + *ppszwClientDescription = CoTaskMemAlloc((wcslen(szValue)+1) * sizeof(WCHAR)); + if (*ppszwClientDescription) + wcscpy(*ppszwClientDescription, szValue); + else + hr = E_OUTOFMEMORY; + } + else + { + hr = E_FAIL; + } + RegCloseKey(hKey); + return hr; +} + +static const INetCfgLockVtbl vt_NetCfgLock = +{ + INetCfgLock_fnQueryInterface, + INetCfgLock_fnAddRef, + INetCfgLock_fnRelease, + INetCfgLock_fnAcquireWriteLock, + INetCfgLock_fnReleaseWriteLock, + INetCfgLock_fnIsWriteLocked +}; + +/*************************************************************** + * INetCfg + */ + +HRESULT +EnumClientServiceProtocol(HKEY hKey, const GUID * pGuid, NetCfgComponentItem ** pHead) +{ + DWORD dwIndex = 0; + DWORD dwSize; + DWORD dwType; + DWORD dwCharacteristics; + WCHAR szName[100]; + WCHAR szText[100]; + HKEY hSubKey, hNDIKey; + NetCfgComponentItem * pLast = NULL, *pCurrent; + + *pHead = NULL; + + do + { + dwCharacteristics = 0; + szText[0] = L'\0'; + + dwSize = sizeof(szName)/sizeof(WCHAR); + if (RegEnumKeyExW(hKey, dwIndex++, szName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + pCurrent = CoTaskMemAlloc(sizeof(NetCfgComponentItem)); + if (!pCurrent) + return E_OUTOFMEMORY; + + pCurrent->bChanged = FALSE; + pCurrent->pNext = NULL; + pCurrent->Status = 0; /* unused */ + pCurrent->szNodeId = 0; /* unused */ + CopyMemory(&pCurrent->ClassGUID, pGuid, sizeof(GUID)); + + if (FAILED(CLSIDFromString(szName, &pCurrent->InstanceId))) + { + CoTaskMemFree(pCurrent); + return E_FAIL; + } + + if (RegOpenKeyExW(hKey, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) + { + /* retrieve Characteristics */ + dwSize = sizeof(DWORD); + pCurrent->dwCharacteristics = 0; + RegQueryValueExW(hSubKey, L"Characteristics", NULL, &dwType, (LPBYTE)&pCurrent->dwCharacteristics, &dwSize); + if (dwType != REG_DWORD) + pCurrent->dwCharacteristics = 0; + + /* retrieve ComponentId */ + pCurrent->szId = NULL; + dwSize = sizeof(szText); + if (RegQueryValueExW(hSubKey, L"ComponentId", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) + { + if (dwType == REG_SZ) + { + szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; + pCurrent->szId = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); + if (pCurrent->szId) + wcscpy(pCurrent->szId, szText); + } + } + + /* retrieve Description */ + pCurrent->szDisplayName = NULL; + dwSize = sizeof(szText); + if (RegQueryValueExW(hSubKey, L"Description", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) + { + if (dwType == REG_SZ) + { + szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; + pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); + if (pCurrent->szDisplayName) + wcscpy(pCurrent->szDisplayName, szText); + } + } + + if (RegOpenKeyExW(hKey, L"NDI", 0, KEY_READ, &hNDIKey) == ERROR_SUCCESS) + { + /* retrieve HelpText */ + pCurrent->szHelpText = NULL; + dwSize = sizeof(szText); + if (RegQueryValueExW(hNDIKey, L"HelpText", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) + { + if (dwType == REG_SZ) + { + szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; + pCurrent->szHelpText = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); + if (pCurrent->szHelpText) + wcscpy(pCurrent->szHelpText, szText); + } + } + + /* retrieve HelpText */ + pCurrent->szBindName = NULL; + dwSize = sizeof(szText); + if (RegQueryValueExW(hNDIKey, L"Service", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) + { + if (dwType == REG_SZ) + { + szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; + pCurrent->szBindName = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); + if (pCurrent->szBindName) + wcscpy(pCurrent->szBindName, szText); + } + } + RegCloseKey(hNDIKey); + } + RegCloseKey(hSubKey); + + if (!pLast) + *pHead = pCurrent; + else + pLast->pNext = pCurrent; + + pLast = pCurrent; + } + } + else + break; + + }while(TRUE); + return S_OK; +} + + + +HRESULT +EnumerateNetworkComponent( + const GUID *pGuid, NetCfgComponentItem ** pHead) +{ + HKEY hKey; + LPOLESTR pszGuid; + HRESULT hr; + WCHAR szName[150]; + + hr = StringFromCLSID(pGuid, &pszGuid); + if (SUCCEEDED(hr)) + { + swprintf(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid); + if (RegOpenKeyExW(hKey, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + hr = EnumClientServiceProtocol(hKey, pGuid, pHead); + RegCloseKey(hKey); + } + CoTaskMemFree(pszGuid); + } + return hr; +} + +HRESULT +EnumerateNetworkAdapter(NetCfgComponentItem ** pHead) +{ + DWORD dwSize, dwIndex; + HDEVINFO hInfo; + SP_DEVINFO_DATA DevInfo; + HKEY hKey; + WCHAR szNetCfg[50]; + WCHAR szAdapterNetCfg[50]; + WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\"; + WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; + NetCfgComponentItem * pLast = NULL, *pCurrent; + + hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT ); + if (!hInfo) + { + return E_FAIL; + } + + dwIndex = 0; + do + { + ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA)); + DevInfo.cbSize = sizeof(DevInfo); + + /* get device info */ + if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo)) + break; + + /* get device software registry path */ + if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize)) + break; + + /* open device registry key */ + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hKey) != ERROR_SUCCESS) + break; + + /* query NetCfgInstanceId for current device */ + dwSize = sizeof(szNetCfg); + if (RegQueryValueExW(hKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS) + { + RegCloseKey(hKey); + break; + } + + /* allocate new INetConnectionItem */ + pCurrent = CoTaskMemAlloc(sizeof(NetCfgComponentItem)); + if (!pCurrent) + break; + + ZeroMemory(pCurrent, sizeof(NetCfgComponentItem)); + CopyMemory(&pCurrent->ClassGUID, &GUID_DEVCLASS_NET, sizeof(GUID)); + CLSIDFromString(szNetCfg, &pCurrent->InstanceId); //FIXME + + /* set bind name */ + pCurrent->szBindName = CoTaskMemAlloc((wcslen(szNetCfg)+1) *sizeof(WCHAR)); + if (pCurrent->szBindName) + wcscpy(pCurrent->szBindName, szNetCfg); + + /* retrieve ComponentId */ + dwSize = sizeof(szAdapterNetCfg); + if (RegQueryValueExW(hKey, L"ComponentId", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) + { + pCurrent->szId = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)); + if (pCurrent->szId) + wcscpy(pCurrent->szId, szAdapterNetCfg); + } + /* set INetCfgComponent::GetDisplayName */ + dwSize = sizeof(szAdapterNetCfg); + if (RegQueryValueExW(hKey, L"DriverDesc", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) + { + pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)); + if (pCurrent->szDisplayName) + wcscpy(pCurrent->szDisplayName, szAdapterNetCfg); + } + + RegCloseKey(hKey); + /* open network connections details */ + wcscpy(&szName[80], szNetCfg); + wcscpy(&szName[118], L"\\Connection"); + + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + /* retrieve pnp instance id */ + dwSize = sizeof(szAdapterNetCfg); + if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) + { + pCurrent->szNodeId = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)); + if (pCurrent->szNodeId) + wcscpy(pCurrent->szNodeId, szAdapterNetCfg); + } + RegCloseKey(hKey); + } + + if (SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)szNetCfg, sizeof(szNetCfg)/sizeof(WCHAR), &dwSize)) + { + szNetCfg[(sizeof(szNetCfg)/sizeof(WCHAR))-1] = L'\0'; + pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szNetCfg)+1) * sizeof(WCHAR)); + if (pCurrent->szDisplayName) + wcscpy(pCurrent->szDisplayName, szNetCfg); + } + + if (pLast) + pLast->pNext = pCurrent; + else + *pHead = pCurrent; + + pLast = pCurrent; + + }while(TRUE); + + SetupDiDestroyDeviceInfoList(hInfo); + return NOERROR; +} + + +HRESULT +FindNetworkComponent( + NetCfgComponentItem * pHead, + LPCWSTR pszwComponentId, + INetCfgComponent **pComponent) +{ + while(pHead) + { + if (!wcsicmp(pHead->szId, pszwComponentId)) + { + return INetCfgComponent_Constructor(NULL, &IID_INetCfgComponent, (LPVOID*)pComponent, pHead); + } + pHead = pHead->pNext; + } + return S_FALSE; +} + + + +HRESULT +WINAPI +INetCfg_fnQueryInterface( + INetCfg * iface, + REFIID iid, + LPVOID * ppvObj) +{ + INetCfgImpl * This = (INetCfgImpl*)iface; + *ppvObj = NULL; + + if (IsEqualIID (iid, &IID_IUnknown) || + IsEqualIID (iid, &IID_INetCfg)) + { + *ppvObj = This; + INetCfg_AddRef(iface); + return S_OK; + } + else if (IsEqualIID (iid, &IID_INetCfgLock)) + { + if (This->bInitialized) + return NETCFG_E_ALREADY_INITIALIZED; + + *ppvObj = (LPVOID)&This->lpVtblLock; + This->hMutex = CreateMutexW(NULL, FALSE, L"NetCfgLock"); + + INetCfgLock_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG +WINAPI +INetCfg_fnAddRef( + INetCfg * iface) +{ + INetCfgImpl * This = (INetCfgImpl*)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + return refCount; +} + +ULONG +WINAPI +INetCfg_fnRelease( + INetCfg * iface) +{ + INetCfgImpl * This = (INetCfgImpl*)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + if (!refCount) + { + CoTaskMemFree (This); + } + return refCount; +} + +HRESULT +STDCALL +INetCfg_fnInitialize( + INetCfg * iface, + PVOID pReserved) +{ + HRESULT hr; + INetCfgImpl *This = (INetCfgImpl *)iface; + + if (This->bInitialized) + return NETCFG_E_ALREADY_INITIALIZED; + + hr = EnumerateNetworkAdapter(&This->pNet); + if (FAILED(hr)) + return hr; + + + hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETCLIENT, &This->pClient); + if (FAILED(hr)) + return hr; + + hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETSERVICE, &This->pService); + if (FAILED(hr)) + return hr; + + + hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETTRANS, &This->pProtocol); + if (FAILED(hr)) + return hr; + + This->bInitialized = TRUE; + return S_OK; +} + +HRESULT +STDCALL +INetCfg_fnUninitialize( + INetCfg * iface) +{ + INetCfgImpl *This = (INetCfgImpl *)iface; + + if (!This->bInitialized) + return NETCFG_E_NOT_INITIALIZED; + + return E_FAIL; +} + + +HRESULT +STDCALL +INetCfg_fnApply( + INetCfg * iface) +{ + INetCfgImpl *This = (INetCfgImpl *)iface; + + if (!This->bInitialized) + return NETCFG_E_NOT_INITIALIZED; + + + return E_NOTIMPL; +} + +HRESULT +STDCALL +INetCfg_fnCancel( + INetCfg * iface) +{ + INetCfgImpl *This = (INetCfgImpl *)iface; + + if (!This->bInitialized) + return NETCFG_E_NOT_INITIALIZED; + + return E_NOTIMPL; +} + +HRESULT +STDCALL +INetCfg_fnEnumComponents( + INetCfg * iface, + const GUID *pguidClass, + IEnumNetCfgComponent **ppenumComponent) +{ + INetCfgImpl *This = (INetCfgImpl *)iface; + + if (!This->bInitialized) + return NETCFG_E_NOT_INITIALIZED; + + if (IsEqualGUID(&GUID_DEVCLASS_NET, pguidClass)) + return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pNet); + else if (IsEqualGUID(&GUID_DEVCLASS_NETCLIENT, pguidClass)) + return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pClient); + else if (IsEqualGUID(&GUID_DEVCLASS_NETSERVICE, pguidClass)) + return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pService); + else if (IsEqualGUID(&GUID_DEVCLASS_NETTRANS, pguidClass)) + return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pProtocol); + else + return E_NOINTERFACE; +} + + +HRESULT +STDCALL +INetCfg_fnFindComponent( + INetCfg * iface, + LPCWSTR pszwComponentId, + INetCfgComponent **pComponent) +{ + HRESULT hr; + INetCfgImpl *This = (INetCfgImpl *)iface; + + if (!This->bInitialized) + return NETCFG_E_NOT_INITIALIZED; + + hr = FindNetworkComponent(This->pClient, pszwComponentId, pComponent); + if (hr == S_OK) + return hr; + + hr = FindNetworkComponent(This->pService, pszwComponentId, pComponent); + if (hr == S_OK) + return hr; + + hr = FindNetworkComponent(This->pProtocol, pszwComponentId, pComponent); + if (hr == S_OK) + return hr; + + return S_FALSE; +} + +HRESULT +STDCALL +INetCfg_fnQueryNetCfgClass( + INetCfg * iface, + const GUID *pguidClass, + REFIID riid, + void **ppvObject) +{ + return E_FAIL; +} + +static const INetCfgVtbl vt_NetCfg = +{ + INetCfg_fnQueryInterface, + INetCfg_fnAddRef, + INetCfg_fnRelease, + INetCfg_fnInitialize, + INetCfg_fnUninitialize, + INetCfg_fnApply, + INetCfg_fnCancel, + INetCfg_fnEnumComponents, + INetCfg_fnFindComponent, + INetCfg_fnQueryNetCfgClass, +}; + +HRESULT WINAPI INetCfg_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) +{ + INetCfgImpl *This; + + if (!ppv) + return E_POINTER; + + This = (INetCfgImpl *) CoTaskMemAlloc(sizeof (INetCfgImpl)); + if (!This) + return E_OUTOFMEMORY; + + This->ref = 1; + This->lpVtbl = (const INetCfg*)&vt_NetCfg; + This->lpVtblLock = (const INetCfgLock*)&vt_NetCfgLock; + This->hMutex = NULL; + This->bInitialized = FALSE; + This->pNet = NULL; + This->pClient = NULL; + This->pService = NULL; + This->pProtocol = NULL; + + if (!SUCCEEDED (INetCfg_QueryInterface ((INetCfg*)This, riid, ppv))) + { + INetCfg_Release((INetCfg*)This); + return E_NOINTERFACE; + } + + INetCfg_Release((INetCfg*)This); + return S_OK; + + + return S_OK; +} diff --git a/reactos/dll/win32/netcfgx/netcfgx.c b/reactos/dll/win32/netcfgx/netcfgx.c index 85f61657530..30b0c23ecee 100644 --- a/reactos/dll/win32/netcfgx/netcfgx.c +++ b/reactos/dll/win32/netcfgx/netcfgx.c @@ -7,12 +7,106 @@ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) */ -#define INITGUID -#include "netcfgx.h" +#include "precomp.h" +#include +#include #define NDEBUG #include +HINSTANCE netcfgx_hInstance; + +static INTERFACE_TABLE InterfaceTable[] = +{ + { + &CLSID_CNetCfg, + INetCfg_Constructor + }, + { + NULL, + NULL + } +}; + +BOOL +WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + netcfgx_hInstance = hinstDLL; + DisableThreadLibraryCalls(netcfgx_hInstance); + break; + default: + break; + } + + return TRUE; +} + +HRESULT +WINAPI +DllCanUnloadNow(void) +{ + return S_FALSE; +} + +STDAPI +DllRegisterServer(void) +{ + //FIXME + // implement registering services + // + return S_OK; +} + +STDAPI +DllUnregisterServer(void) +{ + //FIXME + // implement unregistering services + // + 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; +} + + /* Append a REG_SZ to an existing REG_MULTI_SZ string in the registry. * If the value doesn't exist, create it. * Returns ERROR_SUCCESS if success. Othewise, returns an error code diff --git a/reactos/dll/win32/netcfgx/netcfgx.def b/reactos/dll/win32/netcfgx/netcfgx.def deleted file mode 100644 index 0f866b5f9d6..00000000000 --- a/reactos/dll/win32/netcfgx/netcfgx.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY netcfgx.dll - -EXPORTS -NetClassInstaller@12 - -;EOF \ No newline at end of file diff --git a/reactos/dll/win32/netcfgx/netcfgx.h b/reactos/dll/win32/netcfgx/netcfgx.h deleted file mode 100644 index bd690c1b20a..00000000000 --- a/reactos/dll/win32/netcfgx/netcfgx.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _NETCFGX_H_ -#define _NETCFGX_H_ - -#include -#include -#include - -#endif /* _NETCFGX_H_ */ diff --git a/reactos/dll/win32/netcfgx/netcfgx.rbuild b/reactos/dll/win32/netcfgx/netcfgx.rbuild index edf2fd0bb94..9df9ec67b73 100644 --- a/reactos/dll/win32/netcfgx/netcfgx.rbuild +++ b/reactos/dll/win32/netcfgx/netcfgx.rbuild @@ -1,9 +1,21 @@ - - - netcfgx.c + + ntdll rpcrt4 setupapi kernel32 advapi32 + uuid + iphlpapi + iphlpapi + kernel32 + wine + ole32 + user32 + comctl32 + netcfgx.c + netcfgx.spec + classfactory.c + netcfg_iface.c + inetcfgcomp_iface.c diff --git a/reactos/dll/win32/netcfgx/netcfgx.spec b/reactos/dll/win32/netcfgx/netcfgx.spec new file mode 100644 index 00000000000..565c6694f0e --- /dev/null +++ b/reactos/dll/win32/netcfgx/netcfgx.spec @@ -0,0 +1,16 @@ +2 stdcall DllCanUnloadNow() +3 stdcall DllGetClassObject(ptr ptr ptr) +4 stdcall DllRegisterServer() +5 stdcall DllUnregisterServer() +6 stub HrDiAddComponentToINetCfg +7 stub LanaCfgFromCommandArgs +8 stub ModemClassCoInstaller +9 stub NetCfgDiagFromCommandArgs +10 stub NetCfgDiagRepairRegistryBindings +11 stdcall NetClassInstaller (long ptr ptr) +12 stub NetPropPageProvider +13 stub RasAddBindings +14 stub RasCountBindings +15 stub RasRemoveBindings +16 stub SvchostChangeSvchostGroup +17 stub UpdateLanaConfigUsingAnswerfile \ No newline at end of file diff --git a/reactos/dll/win32/netcfgx/precomp.h b/reactos/dll/win32/netcfgx/precomp.h new file mode 100644 index 00000000000..502fe54fd63 --- /dev/null +++ b/reactos/dll/win32/netcfgx/precomp.h @@ -0,0 +1,48 @@ +#ifndef _PRECOMP_H__ +#define _PRECOMP_H__ + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include +#include +#include +#include +#include + +typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject); +typedef struct { + REFIID riid; + LPFNCREATEINSTANCE lpfnCI; +} INTERFACE_TABLE; + +typedef struct tagNetCfgComponentItem +{ + LPWSTR szDisplayName; //Y + LPWSTR szHelpText; //Y + LPWSTR szId; //Y + LPWSTR szBindName; //Y + LPWSTR szNodeId; //Y + CLSID InstanceId; //Y + CLSID ClassGUID; //Y + DWORD dwCharacteristics; //Y + ULONG Status; //Y + BOOL bChanged; //Y + struct tagNetCfgComponentItem * pNext; +}NetCfgComponentItem; + +/* netcfg_iface.c */ +HRESULT WINAPI INetCfg_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv); + +/* classfactory.c */ +IClassFactory * IClassFactory_fnConstructor(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, REFIID riidInst); + +/* globals */ +extern HINSTANCE netcfgx_hInstance; + +/* inetcfgcomp_iface.c */ +HRESULT STDCALL INetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem); +HRESULT STDCALL IEnumNetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem); + +#endif