- 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
+1 -1
View File
@@ -1,4 +1,4 @@
#include <precomp.h>
#include "precomp.h"
typedef struct
{
@@ -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;
}
+694
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;
}
+96 -2
View File
@@ -7,12 +7,106 @@
* PROGRAMMERS: Hervé Poussineau ([email protected])
*/
#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
-6
View File
@@ -1,6 +0,0 @@
LIBRARY netcfgx.dll
EXPORTS
NetClassInstaller@12
;EOF
-8
View File
@@ -1,8 +0,0 @@
#ifndef _NETCFGX_H_
#define _NETCFGX_H_
#include <windows.h>
#include <setupapi.h>
#include <devguid.h>
#endif /* _NETCFGX_H_ */
+15 -3
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>
+16
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
+48
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