VBoxDrvCfg.cpp revision 575c6ae5723369fc8ababc6dcce572670513a2c1
/* $Id$ */
/** @file
* VBoxDrvCfg.cpp - Windows Driver Manipulation API implementation
*/
/*
* Copyright (C) 2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include <VBox/VBoxDrvCfg-win.h>
#include <setupapi.h>
#include <shlobj.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
static PFNVBOXDRVCFG_LOG g_pfnVBoxDrvCfgLog;
static void *g_pvVBoxDrvCfgLog;
static void *g_pvVBoxDrvCfgPanic;
{
}
{
}
{
void * pvLog = g_pvVBoxDrvCfgLog;
if (pfnLog)
{
char szBuffer[4096] = {0};
}
}
{
void * pvLog = g_pvVBoxDrvCfgLog;
if (pfnLog)
{
char szBuffer[4096] = {0};
}
}
{
void * pvLog = g_pvVBoxDrvCfgLog;
if (pfnLog)
{
char szBuffer[4096] = {0};
}
}
static void vboxDrvCfgPanic()
{
void * pvPanic = g_pvVBoxDrvCfgPanic;
if (pfnPanic)
{
}
}
/* we do not use IPRT Logging because the lib is used in host installer and needs to
* post its msgs to MSI logger */
#define AssertFailed() vboxDrvCfgPanic()
} while (0)
class VBoxDrvCfgStringList
{
public:
VBoxDrvCfgStringList(int aSize);
private:
int mBufSize;
int mSize;
};
{
mSize = 0;
}
{
if (!mBufSize)
return;
for (int i = 0; i < mSize; ++i)
{
}
}
{
{
return hr;
}
++mSize;
return S_OK;
}
{
return E_FAIL;
return S_OK;
}
/*
* inf file manipulation API
*/
typedef struct _INF_INFO
{
typedef struct _INFENUM_CONTEXT
{
static HRESULT vboxDrvCfgInfQueryContext(HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, PINFCONTEXT pCtx)
{
{
LogRel((__FUNCTION__ ": SetupFindFirstLine failed WinEr (%d) for Section(%S), Key(%S)\n", winEr, lpszSection, lpszKey));
return HRESULT_FROM_WIN32(winEr);
}
return S_OK;
}
static HRESULT vboxDrvCfgInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, LPWSTR *lppszValue, PDWORD pcValue)
{
{
winEr = GetLastError();
// Assert(winEr == ERROR_INSUFFICIENT_BUFFER);
if (winEr != ERROR_INSUFFICIENT_BUFFER)
{
return HRESULT_FROM_WIN32(winEr);
}
}
if (!lpszValue)
{
LogRel((__FUNCTION__ ": SetCoTaskMemAlloc failed to alloc mem of size (%d), for iValue(%d)\n", cValue * sizeof (lpszValue[0]), winEr, iValue));
return E_FAIL;
}
{
winEr = GetLastError();
Assert(0);
return HRESULT_FROM_WIN32(winEr);
}
*lppszValue = lpszValue;
if (pcValue)
return S_OK;
}
#if defined(RT_ARCH_AMD64)
# define VBOXDRVCFG_ARCHSTR L"amd64"
#else
# define VBOXDRVCFG_ARCHSTR L"x86"
#endif
{
{
return hr;
}
{
return hr;
}
for (DWORD i = 2; (hr = vboxDrvCfgInfQueryKeyValue(&InfCtx, i, &lpszPlatformCur, &cPlatformCur)) == S_OK; ++i)
{
{
if (bNt)
{
continue;
}
{
continue;
}
bNt = true;
}
else
{
bArch = true;
}
if(lpszPlatform)
}
if (lpszPlatform)
{
if (lpszResult)
{
}
else
{
}
}
else
{
lpszModels = NULL;
}
if (lpszModels)
if (lpszPlatform)
{
*lppszValue = lpszResult;
if (pcValue)
}
return hr;
}
{
{
return hr;
}
{
LogRel((__FUNCTION__ ": vboxDrvCfgInfQueryContext for models (%S) failed, hr = (0x%x)\n", lpszModels, hr));
}
else
{
{
LogRel((__FUNCTION__ ": vboxDrvCfgRegQueryKeyValue for models (%S) failed, hr = (0x%x)\n", lpszModels, hr));
}
}
/* free models string right away */
{
return hr;
}
*lppszPnPId = lpszPnPId;
return S_OK;
}
static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR lpszInfPath, IN DWORD fCopyStyle, OUT LPWSTR lpszDstName, IN DWORD cbDstName, OUT PDWORD pcbDstNameSize, OUT LPWSTR* lpszDstNameComponent)
{
{
{
}
return hr;
}
return S_OK;
}
{
}
{
return vboxDrvCfgInfCopy(lpszInfPath);
}
{
HRESULT hr = vboxDrvCfgInfCopyEx(lpszInfPath, SP_COPY_REPLACEONLY, DstInfName, cbDword, &cbDword, NULL);
if (hr == VBOXDRVCFG_S_INFEXISTS)
{
{
LogRel((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), oem(%S), winEr (%d)\n", lpszInfPath, DstInfName, winEr));
Assert(0);
return HRESULT_FROM_WIN32(winEr);
}
}
return S_OK;
}
static HRESULT vboxDrvCfgCollectInfsSetupDi(const GUID * pGuid, LPCWSTR pPnPId, VBoxDrvCfgStringList & list)
{
int counter = 0;
pGuid, /* IN LPGUID ClassGuid, OPTIONAL */
NULL /*IN HWND hwndParent OPTIONAL */
);
if (hDevInfo != INVALID_HANDLE_VALUE)
{
NULL, /*IN OUT PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
SPDIT_CLASSDRIVER /*IN DWORD DriverType*/
))
{
char DetailBuf[16384];
for (DWORD i = 0; ; i++)
{
NULL, /* IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
SPDIT_CLASSDRIVER , /*IN DWORD DriverType,*/
i, /*IN DWORD MemberIndex,*/
&DrvInfo /*OUT PSP_DRVINFO_DATA DriverInfoData*/
))
{
hDevInfo, /*IN HDEVINFO DeviceInfoSet,*/
NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
&DrvInfo, /*IN PSP_DRVINFO_DATA DriverInfoData,*/
pDrvDetail, /*OUT PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData, OPTIONAL*/
sizeof(DetailBuf), /*IN DWORD DriverInfoDetailDataSize,*/
&dwReq /*OUT PDWORD RequiredSize OPTIONAL*/
))
{
for (WCHAR * pHwId = pDrvDetail->HardwareID; pHwId && *pHwId && pHwId < (TCHAR*)(DetailBuf + sizeof(DetailBuf)/sizeof(DetailBuf[0])) ;pHwId += wcslen(pHwId) + 1)
{
{
if (pDrvDetail->InfFileName)
{
}
}
}
}
else
{
// Assert(0);
}
}
else
{
if (winEr == ERROR_NO_MORE_ITEMS)
{
break;
}
Assert(0);
}
}
NULL, /*IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL*/
SPDIT_CLASSDRIVER/*IN DWORD DriverType*/
);
}
else
{
winEr = GetLastError();
Assert(0);
}
}
else
{
winEr = GetLastError();
Assert(0);
}
return HRESULT_FROM_WIN32(winEr);
}
#if 0
{
if (rc != VINF_SUCCESS)
{
return E_FAIL;
}
return S_OK;
}
{
return S_OK;
}
#endif
VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidClass, IN LPCWSTR lpszClassName, IN LPCWSTR lpszPnPId, IN DWORD Flags)
{
{
for (int i = 0; i < size; ++i)
{
if (pRel)
++pRel;
else
// LogRel(("inf : %S\n", list.get(i)));
}
}
return hr;
}
static HRESULT vboxDrvCfgEnumFiles(LPCWSTR pPattern, PFNVBOXNETCFG_ENUMERATION_CALLBACK pfnCallback, PVOID pContext)
{
if (hEnum != INVALID_HANDLE_VALUE)
{
do
{
{
break;
}
/* next iteration */
if (!bNext)
{
int winEr = GetLastError();
if (winEr != ERROR_NO_MORE_FILES)
{
Assert(0);
}
break;
}
}while (true);
}
else
{
int winEr = GetLastError();
if (winEr != ERROR_NO_MORE_FILES)
{
Assert(0);
}
}
return hr;
}
{
// LogRel(("vboxDrvCfgInfEnumerationCallback: pFileName (%S)\n", pFileName));
HINF hInf = SetupOpenInfFileW(lpszFileName, pContext->InfInfo.lpszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
if (hInf == INVALID_HANDLE_VALUE)
{
winEr = GetLastError();
if (winEr != ERROR_CLASS_MISMATCH)
{
}
return true;
}
{
{
NULL /*__in PVOID Reserved == NULL */
))
{
winEr = GetLastError();
LogRel((__FUNCTION__ ": SetupUninstallOEMInf failed for file (%S), winEr (%d)\n", lpszFileName, winEr));
Assert(0);
}
}
}
else
{
}
return true;
}
VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(LPCWSTR lpszClassName, LPCWSTR lpszPnPId, DWORD Flags)
{
CSIDL_WINDOWS, /* int nFolder*/
NULL, /*HANDLE hToken*/
SHGFP_TYPE_CURRENT, /*DWORD dwFlags*/
{
{
}
else
{
}
}
else
{
}
return hr;
}