- Implement INetCfg, INetCfgLock, INetCfgComponent, IEnumNetCfgComponent interface

- Replace def by spec file
- Replace netcfgx.h by precomp.h to avoid conflicts with netcfgx.h which resides in the psdk

svn path=/trunk/; revision=35996
This commit is contained in:
Johannes Anderwald 2008-09-06 17:22:32 +00:00
parent 53e404a55a
commit 3ac73d668f
9 changed files with 1386 additions and 20 deletions

View file

@ -1,4 +1,4 @@
#include <precomp.h>
#include "precomp.h"
typedef struct
{

View file

@ -0,0 +1,516 @@
#include "precomp.h"
#include <devguid.h>
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;
}

View file

@ -0,0 +1,694 @@
#include "precomp.h"
#include <devguid.h>
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;
}

View file

@ -7,12 +7,106 @@
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/
#define INITGUID
#include "netcfgx.h"
#include "precomp.h"
#include <initguid.h>
#include <devguid.h>
#define NDEBUG
#include <debug.h>
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

View file

@ -1,6 +0,0 @@
LIBRARY netcfgx.dll
EXPORTS
NetClassInstaller@12
;EOF

View file

@ -1,8 +0,0 @@
#ifndef _NETCFGX_H_
#define _NETCFGX_H_
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#endif /* _NETCFGX_H_ */

View file

@ -1,9 +1,21 @@
<module name="netcfgx" type="win32dll" baseaddress="${BASEADDRESS_NETCFGX}" entrypoint="0" installbase="system32" installname="netcfgx.dll">
<importlibrary definition="netcfgx.def" />
<file>netcfgx.c</file>
<module name="netcfgx" type="win32dll" baseaddress="${BASEADDRESS_NETCFGX}" installbase="system32" installname="netcfgx.dll">
<importlibrary definition="netcfgx.spec.def" />
<library>ntdll</library>
<library>rpcrt4</library>
<library>setupapi</library>
<library>kernel32</library>
<library>advapi32</library>
<library>uuid</library>
<library>iphlpapi</library>
<library>iphlpapi</library>
<library>kernel32</library>
<library>wine</library>
<library>ole32</library>
<library>user32</library>
<library>comctl32</library>
<file>netcfgx.c</file>
<file>netcfgx.spec</file>
<file>classfactory.c</file>
<file>netcfg_iface.c</file>
<file>inetcfgcomp_iface.c</file>
</module>

View file

@ -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

View file

@ -0,0 +1,48 @@
#ifndef _PRECOMP_H__
#define _PRECOMP_H__
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include <windows.h>
#include <netcfgx.h>
#include <setupapi.h>
#include <stdio.h>
#include <iphlpapi.h>
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