全自动安装卸载驱动程序的源程序

东坡下载 2011年12月15日 00:53:30

      我本来希望我是往硬件底层驱动程序发展的,本来专业就是电路方面的,这两年也

      做过usb驱动的一些东西,虽然能用,但是心里一直感觉不舒服,对wdm的掌握总感觉有点

      飘忽,所以假期中在看unix的操作系统实现,现在心里有点底了,可是没有真的写过彻底的

      驱动程序,总有点心虚,呵呵,贴个帖子,以前bbs上的,自己也写过,也不知道到哪里了,

      所以直接把人家的贴上来好了,

      [scode=cpp]

      #include stdafx.h

      #include // Make all functions UNICODE safe.

      #include // for the API UpdateDriverForPlugAndPlayDevices().

      #include // for SetupDiXxx functions.

      #include install.h

      int DisplayError(TCHAR * ErrorName)

      {

      DWORD Err = GetLastError();

      LPVOID lpMessageBuffer = NULL;

      if (FormatMessage(

      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,

      NULL,

      Err,

      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

      (LPTSTR) &lpMessageBuffer,

      0,

      NULL ))

      NULL; //_tprintf(TEXT(%s FAILURE: %s\\n),ErrorName,(TCHAR *)lpMessag

      eBuffer);

      else

      NULL; //_tprintf(TEXT(%s FAILURE: (0x%08x)\\n),ErrorName,Err);

      if (lpMessageBuffer) LocalFree( lpMessageBuffer ); // Free system buffer

      SetLastError(Err);

      return FALSE;

      }

      BOOL FindExistingDevice(IN LPTSTR HardwareId)

      {

      HDEVINFO DeviceInfoSet;

      SP_DEVINFO_DATA DeviceInfoData;

      DWORD i,err;

      BOOL Found;

      //

      // Create a Device Information Set with all present devices.

      //

      DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes

      0,

      0,

      DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system

      if (DeviceInfoSet == INVALID_HANDLE_VALUE)

      {

      return DisplayError(TEXT(GetClassDevs(All Present Devices)));

      }

      //_tprintf(TEXT(Search for Device ID: [%s]\\n),HardwareId);

      //

      // Enumerate through all Devices.

      //

      Found = FALSE;

      DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

      for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)

      {

      DWORD DataT;

      LPTSTR p,buffer = NULL;

      DWORD buffersize = 0;

      //

      // We won't know the size of the HardwareID buffer until we call

      // this function. So call it with a null to begin with, and then

      // use the required buffer size to Alloc the nessicary space.

      // Keep calling we have success or an unknown failure.

      //

      while (!SetupDiGetDeviceRegistryProperty(

      DeviceInfoSet,

      &DeviceInfoData,

      SPDRP_HARDWAREID,

      &DataT,

      (PBYTE)buffer,

      buffersize,

      &buffersize))

      {

      if (GetLastError() == ERROR_INVALID_DATA)

      {

      //

      // May be a Legacy Device with no HardwareID. Continue.

      //

      break;

      }

      else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

      {

      //

      // We need to change the buffer size.

      //

      if (buffer)

      LocalFree(buffer);

      buffer = (char *)LocalAlloc(LPTR,buffersize);

      }

      else

      {

      //

      // Unknown Failure.

      //

      DisplayError(TEXT(GetDeviceRegistryProperty));

      goto cleanup_DeviceInfo;

      }

      }

      if (GetLastError() == ERROR_INVALID_DATA)

      continue;

      //

      // Compare each entry in the buffer multi-sz list with our HardwareID.

      //

      for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR))

      {

      //_tprintf(TEXT(Compare device ID: [%s]\\n),p);

      if (!_tcscmp(HardwareId,p))

      {

      //_tprintf(TEXT(Found! [%s]\\n),p);

      Found = TRUE;

      break;

      }

      }

      if (buffer) LocalFree(buffer);

      if (Found) break;

      }

      if (GetLastError() != NO_ERROR)

      {

      DisplayError(TEXT(EnumDeviceInfo));

      }

      //

      // Cleanup.

      //

      cleanup_DeviceInfo:

      err = GetLastError();

      SetupDiDestroyDeviceInfoList(DeviceInfoSet);

      SetLastError(err);

      return err == NO_ERROR; //???

      }

      BOOL

      InstallRootEnumeratedDriver(IN LPTSTR HardwareId,

      IN LPTSTR INFFile,

      OUT PBOOL RebootRequired OPTIONAL

      )

      {

      HDEVINFO DeviceInfoSet = 0;

      SP_DEVINFO_DATA DeviceInfoData;

      GUID ClassGUID;

      TCHAR ClassName[MAX_CLASS_NAME_LEN];

      DWORD err;

      //

      // Use the INF File to extract the Class GUID.

      //

      if (!SetupDiGetINFClass(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0))

      {

      return DisplayError(TEXT(GetINFClass));

      }

      //

      // Create the container for the to-be-created Device Information Element.

      //

      DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);

      if(DeviceInfoSet == INVALID_HANDLE_VALUE)

      {

      return DisplayError(TEXT(CreateDeviceInfoList));

      }

      //

      // Now create the element.

      // Use the Class GUID and Name from the INF file.

      //

      DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

      if (!SetupDiCreateDeviceInfo(DeviceInfoSet,

      ClassName,

      &ClassGUID,

      NULL,

      0,

      DICD_GENERATE_ID,

      &DeviceInfoData))

      {

      DisplayError(TEXT(CreateDeviceInfo));

      goto cleanup_DeviceInfo;

      }

      //

      // Add the HardwareID to the Device's HardwareID property.

      //

      if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,

      &DeviceInfoData,

      SPDRP_HARDWAREID,

      (LPBYTE)HardwareId,

      (lstrlen(HardwareId)+1+1)*sizeof(TCHAR)))

      {

      DisplayError(TEXT(SetDeviceRegistryProperty));

      goto cleanup_DeviceInfo;

      }

      //

      // Transform the registry element into an actual devnode

      // in the PnP HW tree.

      //

      if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,

      DeviceInfoSet,

      &DeviceInfoData))

      {

      DisplayError(TEXT(CallClassInstaller(REGISTERDEVICE)));

      goto cleanup_DeviceInfo;

      }

      //

      // The element is now registered. We must explicitly remove the

      // device using DIF_REMOVE, if we encounter any failure from now on.

      //

      //

      // Install the Driver.

      //

      if (!UpdateDriverForPlugAndPlayDevices(0,

      HardwareId,

      INFFile,

      INSTALLFLAG_FORCE,

      RebootRequired))

      {

      DWORD err = GetLastError();

      DisplayError(TEXT(UpdateDriverForPlugAndPlayDevices));

      if (!SetupDiCallClassInstaller(

      DIF_REMOVE,

      DeviceInfoSet,

      &DeviceInfoData))

      {

      DisplayError(TEXT(CallClassInstaller(REMOVE)));

      }

      SetLastError(err);

      }

      //

      // Cleanup.

      //

      cleanup_DeviceInfo:

      err = GetLastError();

      SetupDiDestroyDeviceInfoList(DeviceInfoSet);

      SetLastError(err);

      return err == NO_ERROR;

      }

      int InstallDriver(_TCHAR *InfName, _TCHAR *HardwareID)

      {

      WIN32_FIND_DATA FindFileData;

      BOOL RebootRequired = 0; // Must be cleared.

      _TCHAR *FName, *HWID;

      FName = InfName;

      HWID = HardwareID;

      if (FindFirstFile(FName,&FindFileData)==INVALID_HANDLE_VALUE)

      {

      //_tprintf(TEXT( File not found.\\n));

      //_tprintf(TEXT(usage: install \\n));

      return 2; // Install Failure

      }

      //

      // Look to see if this device allready exists.

      //

      if (FindExistingDevice(HWID))

      {

      //

      // No Need to Create a Device Node, just call our API.

      //

      if (!UpdateDriverForPlugAndPlayDevices(0, // No Window Handle

      HWID, // Hardware ID

      FName, // FileName

      INSTALLFLAG_FORCE,

      &RebootRequired))

      {

      DisplayError(TEXT(UpdateDriverForPlugAndPlayDevices));

      return 2; // Install Failure

      }

      }

      else

      {

      if (GetLastError()!= ERROR_NO_MORE_ITEMS)

      {

      //

      // An unknown failure from FindExistingDevice()

      //

      //_tprintf(TEXT((IERROR_NO_MORE_ITEMS)\\n));

      //_tprintf(TEXT((Install Failure! Code = 2)\\n));

      return 2; // Install Failure

      }

      //

      // Driver Does not exist, Create and call the API.

      // HardwareID must be a multi-sz string, which argv[2] is.

      //

      if (!InstallRootEnumeratedDriver(HWID, // HardwareID

      FName, // FileName

      &RebootRequired))

      {

      //_tprintf(TEXT((InstallRootEnumeratedDriver Failure! Code = 2)\\n

      ));

      return 2; // Install Failure

      }

      }

      //_tprintf(TEXT(Driver Installed successfully.\\n));

      if (RebootRequired)

      {

      //_tprintf(TEXT((Reboot Required)\\n));

      return 1; // Install Success, reboot required.

      }

      return 0; // Install Success, no reboot required.

      }

      int RemoveDriver(_TCHAR *HardwareID)

      {

      HDEVINFO DeviceInfoSet;

      SP_DEVINFO_DATA DeviceInfoData;

      DWORD i,err;

      DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes

      0,

      0,

      DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system

      if (DeviceInfoSet == INVALID_HANDLE_VALUE)

      {

      DisplayError(TEXT(GetClassDevs(All Present Devices)));

      return 1;

      }

      //

      // Enumerate through all Devices.

      //

      DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

      for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)

      {

      DWORD DataT;

      LPTSTR p,buffer = NULL;

      DWORD buffersize = 0;

      //

      // We won't know the size of the HardwareID buffer until we call

      // this function. So call it with a null to begin with, and then

      // use the required buffer size to Alloc the nessicary space.

      // Keep calling we have success or an unknown failure.

      //

      while (!SetupDiGetDeviceRegistryProperty(

      DeviceInfoSet,

      &DeviceInfoData,

      SPDRP_HARDWAREID,

      &DataT,

      (PBYTE)buffer,

      buffersize,

      &buffersize))

      {

      if (GetLastError() == ERROR_INVALID_DATA)

      {

      //

      // May be a Legacy Device with no HardwareID. Continue.

      //

      break;

      }

      else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

      {

      //

      // We need to change the buffer size.

      //

      if (buffer)

      LocalFree(buffer);

      buffer = (char *)LocalAlloc(LPTR,buffersize);

      }

      else

      {

      //

      // Unknown Failure.

      //

      DisplayError(TEXT(GetDeviceRegistryProperty));

      goto cleanup_DeviceInfo;

      }

      }

      if (GetLastError() == ERROR_INVALID_DATA)

      continue;

      //

      // Compare each entry in the buffer multi-sz list with our HardwareID.

      //

      for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR))

      {

      //_tprintf(TEXT(Compare device ID: [%s]\\n),p);

      if (!_tcscmp(HardwareID,p))

      {

      //_tprintf(TEXT(Found! [%s]\\n),p);

      //

      // Worker function to remove device.

      //

      if (!SetupDiCallClassInstaller(DIF_REMOVE,

      DeviceInfoSet,

      &DeviceInfoData))

      {

      DisplayError(TEXT(CallClassInstaller(REMOVE)));

      }

      break;

      }

      }

      if (buffer) LocalFree(buffer);

      }

      if ((GetLastError()!=NO_ERROR)&&(GetLastError()!=ERROR_NO_MORE_ITEMS))

      {

      DisplayError(TEXT(EnumDeviceInfo));

      }

      //

      // Cleanup.

      //

      cleanup_DeviceInfo:

      err = GetLastError();

      SetupDiDestroyDeviceInfoList(DeviceInfoSet);

      return err;

      }

      [/scode]

      更多精彩内容请点击

强力卸载软件

专题