Пример #1
0
VOID
EnumerateDrivers(PVOID Context, HDEVINFO hList, PSP_DEVINFO_DATA pInfoData)
{
    HSPFILEQ hQueue;
    SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
    SP_DRVINFO_DATA DriverInfoData;
    DWORD Result;

    DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
    if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
        return;

    DeviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
    if (!SetupDiSetDeviceInstallParams(hList, pInfoData, &DeviceInstallParams))
        return;

    if (!SetupDiBuildDriverInfoList(hList, pInfoData, SPDIT_CLASSDRIVER))
        return;

    DriverInfoData.cbSize = sizeof(DriverInfoData);
    if (!SetupDiEnumDriverInfoW(hList, pInfoData, SPDIT_CLASSDRIVER, 0, &DriverInfoData))
        return;

    DriverInfoData.cbSize = sizeof(DriverInfoData);
    if (!SetupDiSetSelectedDriverW(hList, pInfoData, &DriverInfoData))
         return;

    hQueue = SetupOpenFileQueue();
    if (hQueue == (HSPFILEQ)INVALID_HANDLE_VALUE)
        return;

    DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
    if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
    {
        SetupCloseFileQueue(hQueue);
        return;
    }

    DeviceInstallParams.FileQueue = hQueue;
    DeviceInstallParams.Flags |= DI_NOVCP;

    if (!SetupDiSetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams))
    {
        SetupCloseFileQueue(hQueue);
        return;
    }

    if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hList, pInfoData))
    {
        SetupCloseFileQueue(hQueue);
        return;
    }


    /* enumerate the driver files */
    SetupScanFileQueueW(hQueue, SPQ_SCAN_USE_CALLBACK, NULL, DriverFilesCallback, Context, &Result);
    SetupCloseFileQueue(hQueue);
}
Пример #2
0
HRESULT
xDiEnumDriverFiles(
	__in_opt HWND Owner,
	__in LPCWSTR OemInfFullPath,
	__in DWORD Flags,
	__in XDI_ENUM_DRIVER_FILE_CALLBACK EnumCallback,
	__in LPVOID EnumContext)
{
	HRESULT hr;
	BOOL success;

	WCHAR infFullPath[MAX_PATH];

	DWORD n = GetFullPathNameW(OemInfFullPath, MAX_PATH, infFullPath, NULL);
	if (0 == n)
	{
		hr = HRESULT_FROM_WIN32(GetLastError());
		hr = (SUCCEEDED(hr)) ? E_FAIL : hr;
		goto error0;
	}

	HDEVINFO devInfoSet = SetupDiCreateDeviceInfoList(NULL, Owner);
	if (INVALID_HANDLE_VALUE == devInfoSet)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error0;
	}

	SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) };

	success = SetupDiCreateDeviceInfoW(
		devInfoSet,
		L"XDI_Temporary_Enumerator",
		&GUID_NULL,
		NULL,
		NULL,
		DICD_GENERATE_ID,
		&devInfoData);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error1;
	}

	HSPFILEQ fileQueueHandle = SetupOpenFileQueue();

	if (INVALID_HANDLE_VALUE == fileQueueHandle)
	{
		// Error from SetupOpenFileQueue is only from out-of-memory situation
		// without the last error set
		hr = E_OUTOFMEMORY;
		goto error2;
	}

	SP_DEVINSTALL_PARAMS devInstallParams = {sizeof(SP_DEVINSTALL_PARAMS)};

	success = SetupDiGetDeviceInstallParamsW(
		devInfoSet,
		&devInfoData,
		&devInstallParams);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error3;
	}

	//
	// Specify the search path
	//

	hr = StringCchCopyW(
		devInstallParams.DriverPath,
		MAX_PATH,
		infFullPath);

	if (FAILED(hr))
	{
		goto error3;
	}

	devInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
	devInstallParams.FileQueue = fileQueueHandle;
	devInstallParams.Flags |= DI_NOVCP;
	devInstallParams.Flags |= DI_ENUMSINGLEINF;

	success = SetupDiSetDeviceInstallParamsW(
		devInfoSet,
		&devInfoData,
		&devInstallParams);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error3;
	}

	//
	// use DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE if possible 
	// to ensure we look at duplicate nodes (which is broken in itself)
	//
#ifndef DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE
#define DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE  0x08000000L  // Don't remove identical driver nodes from the class list
#endif

	if (xDipWindowsXPOrLater())
	{
		devInstallParams.FlagsEx |= DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE;

		success = SetupDiSetDeviceInstallParamsW(
			devInfoSet,
			&devInfoData,
			&devInstallParams);

		if (!success)
		{
			devInstallParams.FlagsEx &= ~DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE;
		}
	}

	//
	// Build a class driver list with every driver
	//

	success = SetupDiBuildDriverInfoList(
		devInfoSet,
		&devInfoData,
		SPDIT_CLASSDRIVER);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error3;
	}

	SP_DRVINFO_DATA drvInfoData = { sizeof(SP_DRVINFO_DATA) };

	for (DWORD index = 0; ; ++index)
	{
		success = SetupDiEnumDriverInfoW(
			devInfoSet, 
			&devInfoData, 
			SPDIT_CLASSDRIVER, 
			index, 
			&drvInfoData);

		if (!success)
		{
			break;
		}

		SP_DRVINFO_DETAIL_DATA drvInfoDetail = { sizeof(SP_DRVINFO_DETAIL_DATA) };

		success = SetupDiGetDriverInfoDetailW(
			devInfoSet, 
			&devInfoData,
			&drvInfoData,
			&drvInfoDetail,
			sizeof(SP_DRVINFO_DETAIL_DATA),
			NULL);

		if (!success && ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			hr = HRESULT_FROM_SETUPAPI(GetLastError());
			goto error4;
		}

		success = SetupDiSetSelectedDriverW(
			devInfoSet,
			&devInfoData,
			&drvInfoData);

		if (!success)
		{
			hr = HRESULT_FROM_SETUPAPI(GetLastError());
			goto error4;
		}

		if (Flags & XDI_EDF_NO_CLASS_INSTALLER)
		{
			success = SetupDiInstallDriverFiles(
				devInfoSet, &devInfoData);

			if (!success)
			{
				hr = HRESULT_FROM_SETUPAPI(GetLastError());
				goto error4;
			}
		}
		else
		{
			success = SetupDiCallClassInstaller(
				DIF_INSTALLDEVICEFILES, devInfoSet, &devInfoData);

			if (!success)
			{
				hr = HRESULT_FROM_SETUPAPI(GetLastError());
				goto error4;
			}
		}
	}

	//
	// SPQ_SCAN_USE_CALLBACK_EX checks the digital signature of the file
	// We do not want to check the signature here.
	//
	// SPQ_SCAN_FILE_PRESENCE avoids checking the digital signature of the file
	// in Windows XP or later. (Not in Windows 2000) when used 
	// with SPQ_SCAN_USE_CALLBACK_EX
	//

	XDI_ENUM_FQS_CONTEXT fqsContext = {0};
	fqsContext.Callback = EnumCallback;
	fqsContext.CallbackContext = EnumContext;

	DWORD scanResult;
	success = SetupScanFileQueueW(
		fileQueueHandle, 
		SPQ_SCAN_USE_CALLBACK,
		// SPQ_SCAN_USE_CALLBACKEX | SPQ_SCAN_FILE_PRESENCE,
		Owner,
		xDipEnumFileQueueScanCallback,
		&fqsContext,
		&scanResult);

	if (!success)
	{
		//
		// SetupScanFileQueue may fail using SPQ_SCAN_FILE_PRESENSE flag
		// Try again without SPQ_SCAN_FILE_PRESENSE
		// (when using SPQ_SCAN_USE_CALLBACKEX)
		//
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		goto error4;
	}

	hr = S_OK;

#pragma warning(disable: 4533) // to use goto in cpp

error4:

	SetupDiDestroyDriverInfoList(
		devInfoSet, &devInfoData, SPDIT_CLASSDRIVER);

error3:

	SetupCloseFileQueue(fileQueueHandle);

error2:

	SetupDiDeleteDeviceInfo(devInfoSet, &devInfoData);

error1:

	SetupDiDestroyDeviceInfoList(devInfoSet);

error0:

#pragma warning(default: 4533)

	return hr;
}
Пример #3
0
/* Directory and InfFile MUST NOT be specified simultaneously */
static BOOL
SearchDriver(
    IN PDEVINSTDATA DevInstData,
    IN LPCWSTR Directory OPTIONAL,
    IN LPCWSTR InfFile OPTIONAL)
{
    SP_DEVINSTALL_PARAMS_W DevInstallParams = {0,};
    BOOL ret;

    DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
    if (!SetupDiGetDeviceInstallParamsW(DevInstData->hDevInfo, &DevInstData->devInfoData, &DevInstallParams))
    {
        TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
        return FALSE;
    }
    DevInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;

    if (InfFile)
    {
        DevInstallParams.Flags |= DI_ENUMSINGLEINF;
        wcsncpy(DevInstallParams.DriverPath, InfFile, MAX_PATH);
    }
    else if (Directory)
    {
        DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
        wcsncpy(DevInstallParams.DriverPath, Directory, MAX_PATH);
    }
    else
    {
        DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
        *DevInstallParams.DriverPath = '\0';
    }

    ret = SetupDiSetDeviceInstallParamsW(
        DevInstData->hDevInfo,
        &DevInstData->devInfoData,
        &DevInstallParams);
    if (!ret)
    {
        TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
        return FALSE;
    }

    ret = SetupDiBuildDriverInfoList(
        DevInstData->hDevInfo,
        &DevInstData->devInfoData,
        SPDIT_COMPATDRIVER);
    if (!ret)
    {
        TRACE("SetupDiBuildDriverInfoList() failed with error 0x%x\n", GetLastError());
        return FALSE;
    }

    DevInstData->drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
    ret = SetupDiEnumDriverInfoW(
        DevInstData->hDevInfo,
        &DevInstData->devInfoData,
        SPDIT_COMPATDRIVER,
        0,
        &DevInstData->drvInfoData);
    if (!ret)
    {
        if (GetLastError() == ERROR_NO_MORE_ITEMS)
            return FALSE;
        TRACE("SetupDiEnumDriverInfo() failed with error 0x%x\n", GetLastError());
        return FALSE;
    }

    return TRUE;
}
Пример #4
0
void InstallDriver( HANDLE DeviceInformation, SP_DEVINFO_DATA* DeviceData )
{
    SP_DEVINSTALL_PARAMS_W deviceInstallParams;
    SP_DRVINFO_DATA_V2_W driverData;
    UINT32 reboot = 0;
    HANDLE module;
    DWORD address;
    BYTE *addr;

    if (!SetupDiSetSelectedDevice(DeviceInformation, DeviceData))
    {
        Log(L"Set Selected Device fail.");
        return;
    }

    Memory_Clear(&deviceInstallParams, sizeof(SP_DEVINSTALL_PARAMS_W));

    if (sizeof(int*) == 8)
    {
        deviceInstallParams.cbSize = 584;
    }
    else
    {
        deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
    }

    if (!SetupDiGetDeviceInstallParamsW(DeviceInformation, DeviceData, &deviceInstallParams))
    {
        Log(L"Get Device Install Params fail.");
        return;
    }

    String_Copy(deviceInstallParams.DriverPath, L"C:\\mij\\drivers\\MijXinput.inf");

    deviceInstallParams.Flags |= 65536;

    if (!SetupDiSetDeviceInstallParamsW(DeviceInformation, DeviceData, &deviceInstallParams))
    {
        Log(L"Set Device Install Params fail.");
        return;
    }

    if (!SetupDiBuildDriverInfoList(DeviceInformation, DeviceData, SPDIT_COMPATDRIVER))
    {
        Log(L"Building Driver Info List fail.");
        return;
    }

    if (!SetupDiSelectBestCompatDrv(DeviceInformation, DeviceData))
    {
        Log(L"Select Best Compatible Driver fail.");
        return;
    }

    Memory_Clear(&driverData, sizeof(SP_DRVINFO_DATA_V2_W));
    driverData.cbSize = sizeof(SP_DRVINFO_DATA_V2_W);

    if (!SetupDiGetSelectedDriverW(DeviceInformation, DeviceData, &driverData))
    {
        Log(L"Get MotioninJoy Driver fail.");
        return;
    }

    //DiInstallDevice willfully returns 0xE0000235 (ERROR_IN_WOW64) in a WOW64 environment.
    //I don't know if this was a security restraint but there is no reason why this function
    //should not work under WOW64. All we have to do is insert one, literally one jmp patch to
    //skip the WOW64 check and the function succeeds as normal.
    module = Module_GetHandle(L"newdev.dll");
    address = Module_GetProcedureAddress(module, "DiInstallDevice");
    address += 0x134;
    addr = address;

    if ((*addr) == 0x74) //je
    {
        DWORD oldPageProtection = 0;

        //We firstly have to remove page protection of course.
        VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &oldPageProtection);

        //patch to jne
        *addr = 0x75;

        //Lastly, make it look like we were never even there by restoring protection
        VirtualProtect(addr, 1, oldPageProtection, &oldPageProtection);
    }

    if (!DiInstallDevice(NULL, DeviceInformation, DeviceData, &driverData, 0, &reboot))
    {
        Log(L"Install MotioninJoy Driver fail.");
    }
}