Пример #1
0
GUID Inf2ClassGUID( __inout std::wstring& pathName, __out std::wstring& classStr ) {

    GUID ClassGUID;
    wchar_t ClassName[1+MAX_CLASS_NAME_LEN];
    std::vector< wchar_t > InfPath( 0 );
    DWORD pathSize = MAX_PATH;
    ClassName[MAX_CLASS_NAME_LEN] = L'\0';

    while ( pathSize > InfPath.size() ) {

        InfPath.resize( 1 + pathSize );

        pathSize = GetFullPathName(pathName.c_str(), static_cast<DWORD>(InfPath.size()) ,&InfPath[0], NULL);

        if ( 0 == pathSize ) {
            HRESULT hr = HRESULT_FROM_WIN32( GetLastError() );
            LogResult( hr, "GetFullPathName('%ls') Failed", pathName.c_str() );
            throw hr;
        }
    }

    //
    // Use the INF File to extract the Class GUID.
    //
    if (!SetupDiGetINFClassW(&InfPath[0],&ClassGUID,ClassName,sizeof(ClassName)/sizeof(ClassName[0]),0))
    {
        HRESULT hr = HRESULT_FROM_WIN32( GetLastError() );
        LogResult( hr, "SetupDiGetINFClass('%ls') Failed", &InfPath[0] );
        throw hr;
    }

    pathName = &InfPath[0];
    classStr = ClassName;
    return ClassGUID;

} //GUID Inf2ClassGUID( __in const std::wstring& pathName )
Пример #2
0
UINT
pxDiMsiInstallNetworkComponent(
	__in MSIHANDLE hInstall, 
	__in const XDIMSI_PROCESS_RECORD* ProcessRecord)
{
	//
	// InfPath: <inf-path>   e.g. c:\program files\ndas\drivers\netlpx.inf
	// Param: <component-id> e.g. nkc_lpx
	//

	HRESULT hr;
	GUID classGuid;
	WCHAR className[MAX_CLASS_NAME_LEN];

	BOOL success = SetupDiGetINFClassW(
		ProcessRecord->InfPath,
		&classGuid,
		className,
		MAX_CLASS_NAME_LEN,
		NULL);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		//
		// Invalid Class GUID in the inf file
		//
		pxMsiTraceW(hInstall, L"SetupDiGetINFClass failed, hr=0x%x\n", hr);
		return ERROR_INSTALL_FAILURE;
	}

	//
	// Pre-install the OEM INF file to trigger the installation of
	// the component by the component id later (xDiInstallNetComponent)
	//

	WCHAR oemInfPath[MAX_PATH];
	DWORD oemInfPathLength;
	LPWSTR oemInfName;

	XDIMSI_DIALOG_ACTIVATOR_CONTEXT daContext;

	pxDiMsiDialogActivatorStart(&daContext);

	success = SetupCopyOEMInfW(
		ProcessRecord->InfPath,
		NULL,
		SPOST_PATH,
		0,
		oemInfPath,
		RTL_NUMBER_OF(oemInfPath),
		NULL,
		NULL);

	pxDiMsiDialogActivatorStop(&daContext);

	if (!success)
	{
		hr = HRESULT_FROM_SETUPAPI(GetLastError());
		pxMsiTraceW(hInstall, L"SetupCopyOEMInf failed, hr=0x%x\n", hr);
		return ERROR_INSTALL_FAILURE;
	}

	hr = pxDiMsiSetInfPathInRegistry(
		hInstall, 
		oemInfPath, 
		ProcessRecord->RegRoot, 
		ProcessRecord->RegKey, 
		ProcessRecord->RegName);

	if (FAILED(hr))
	{
		pxMsiTraceW(hInstall, L"pxMsiSetInfPathInRegistry failed, hr=0x%x\n", hr);
	}

	while (TRUE)
	{
		pxDiMsiDialogActivatorStart(&daContext);

		hr = xDiInstallNetComponent(
			&classGuid,
			ProcessRecord->HardwareId, 
			15*1000,
			L"Windows Installer", 
			NULL);

		pxDiMsiDialogActivatorStop(&daContext);

		if (FAILED(hr))
		{
			pxMsiTraceW(hInstall, L"InstallNetComponent failed, hr=0x%x\n", hr);

			// 0, IDABORT, IDRETRY, IDIGNORE
			UINT response = pxMsiErrorMessageBox(hInstall, ProcessRecord->ErrorNumber, hr);
			switch (response)
			{
			case IDRETRY:
				continue;
			case IDIGNORE:
				break;
			case 0:
			case IDABORT:
			default:
				return ERROR_INSTALL_FAILURE;
			}
		}

		break;
	}

	//
	// The followings actions are not critical ones
	// Just log errors if any and return ERROR_SUCCESS
	//

	if (XDI_S_REBOOT == hr) 
	{
		pxMsiQueueScheduleReboot(hInstall);
	}

	return ERROR_SUCCESS;
}
Пример #3
0
static
void
create_ramdisk_device(std::string full_inf_file_path,
                      std::string hardware_id) {
  GUID class_guid;
  WCHAR class_name_w[MAX_CLASS_NAME_LEN];
  auto success =
    SetupDiGetINFClassW(w32util::widen(full_inf_file_path).c_str(),
                        &class_guid,
                        class_name_w, safe::numelementsf(class_name_w),
                        nullptr);
  if (!success) w32util::throw_windows_error();

  /* don't install device if it already exists */
  auto create_device = true;
  {
    HDEVINFO device_info_set =
      SetupDiGetClassDevsEx(&class_guid, nullptr, nullptr, 0,
			    nullptr, nullptr, nullptr);
    if (device_info_set == INVALID_HANDLE_VALUE) {
      w32util::throw_setupapi_error();
    }

    SP_DEVINFO_DATA device_info_data;
    zero_object(device_info_data);
    device_info_data.cbSize = sizeof(device_info_data);
    for (DWORD idx = 0;
	 create_device &&
	 SetupDiEnumDeviceInfo(device_info_set, idx, &device_info_data);
	 ++idx) {
      /* first get hardware id reg key for this device info */
      CHAR buffer[1024];
      BOOL success_prop =
	SetupDiGetDeviceRegistryPropertyA(device_info_set,
					  &device_info_data,
					  SPDRP_HARDWAREID,
					  nullptr,
					  (PBYTE) buffer,
					  sizeof(buffer),
					  nullptr);
      if (!success_prop) w32util::throw_setupapi_error();

      PCHAR bp = buffer;
      while(*bp) {
	if (!strcmp(bp, hardware_id.c_str())) {
	  create_device = false;
	  break;
	}
	bp += strlen(bp) + 1;
      }
    }
  }

  // device already exists, no need to create it
  if (!create_device) return;

  auto device_info_set =
    SetupDiCreateDeviceInfoList(&class_guid, NULL);
  if (device_info_set == INVALID_HANDLE_VALUE) w32util::throw_setupapi_error();
  auto _destroy_device_info_set =
    safe::create_deferred(SetupDiDestroyDeviceInfoList, device_info_set);

  SP_DEVINFO_DATA device_info_data;
  zero_object(device_info_data);
  device_info_data.cbSize = sizeof(device_info_data);
  auto success_create_device_info =
    SetupDiCreateDeviceInfoW(device_info_set, class_name_w,
                             &class_guid, nullptr, 0,
                             DICD_GENERATE_ID, &device_info_data);
  if (!success_create_device_info) w32util::throw_setupapi_error();

  // TODO: runtime stack array is a GCC extension
  auto reg_hardware_id_len = hardware_id.size() + 2;
  auto reg_hardware_id_size = reg_hardware_id_len * sizeof(WCHAR);
  auto reg_hardware_id = std::unique_ptr<WCHAR[]>(new WCHAR[reg_hardware_id_len]);
  memset(reg_hardware_id.get(), 0, reg_hardware_id_size);
  memcpy(reg_hardware_id.get(), w32util::widen(hardware_id).data(),
         hardware_id.size() * sizeof(WCHAR));

  auto success_set_hardware_id =
    SetupDiSetDeviceRegistryPropertyW(device_info_set,
                                      &device_info_data,
                                      SPDRP_HARDWAREID,
                                      (BYTE *) reg_hardware_id.get(),
                                      reg_hardware_id_size);
  if (!success_set_hardware_id) w32util::throw_setupapi_error();

  auto success_class_installer =
    SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info_set,
                              &device_info_data);
  if (!success_class_installer) w32util::throw_setupapi_error();

  create_ramdisk_hardware_keys(device_info_set, &device_info_data);
}