RSS订阅 | 匿名投稿
您的位置:网站首页 > 驱动 > 正文

delphi版inf方式加载驱动

作者:admin 来源: 日期:2011/8/18 13:20:43 人气: 标签:

 program bb;

uses
   Windows;
  
const
   MAX_CLASS_NAME_LEN = 128;
   DIF_REMOVE = $00000005;
   DICD_GENERATE_ID = $00000001;
   INSTALLFLAG_FORCE = $00000001;
   SPDRP_HARDWAREID = $00000001;
   DIF_REGISTERDEVICE = $00000019;
   DIGCF_PRESENT = $0002;
   DIGCF_ALLCLASSES = $0004;

   SetupApiModuleName = 'SetupApi.dll';
   NewDevModuleName = 'newdev.dll';

type
   ULONG_PTR = DWORD;
   DI_FUNCTION = UINT; // Function type for device installer
   HDEVINFO = Pointer;

   PSPDevInfoData = ^TSPDevInfoData;
   SP_DEVINFO_DATA = packed record
     cbSize: DWORD;
     ClassGuid: TGUID;
     DevInst: DWORD; // DEVINST handle
     Reserved: ULONG_PTR;
  end;
  
   {$EXTERNALSYM SP_DEVINFO_DATA}
   TSPDevInfoData = SP_DEVINFO_DATA;

  function SetupDiGetClassDevs(ClassGuid: PGUID; const Enumerator: PAnsiChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall;external 'Setupapi.dll' name 'SetupDiGetClassDevsA';
  function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; var DeviceInfoData: TSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiEnumDeviceInfo';
  function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO; const DeviceInfoData: TSPDevInfoData; Property_: DWORD; var PropertyRegDataType: DWORD; PropertyBuffer: PBYTE; PropertyBufferSize: DWORD; var RequiredSize: DWORD): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiGetDeviceRegistryPropertyA';
  function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiDestroyDeviceInfoList';
  function SetupDiGetINFClass(const InfName: PAnsiChar; var ClassGuid: TGUID; ClassName: PAnsiChar; ClassNameSize: DWORD; RequiredSize: PDWORD): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiGetINFClassA';
  function SetupDiCreateDeviceInfoList(ClassGuid: PGUID; hwndParent: HWND): HDEVINFO; stdcall;external 'Setupapi.dll' name 'SetupDiCreateDeviceInfoList';
  function SetupDiCreateDeviceInfo(DeviceInfoSet: HDEVINFO; const DeviceName: PAnsiChar; var ClassGuid: TGUID; const DeviceDescription: PAnsiChar; hwndParent: HWND; CreationFlags: DWORD; DeviceInfoData: PSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiCreateDeviceInfoA';
  function SetupDiSetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO; var DeviceInfoData: TSPDevInfoData; Property_: DWORD; const PropertyBuffer: PBYTE; PropertyBufferSize: DWORD): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiSetDeviceRegistryPropertyA';
  function SetupDiCallClassInstaller(InstallFunction: DI_FUNCTION; DeviceInfoSet: HDEVINFO; DeviceInfoData: PSPDevInfoData): LongBool; stdcall;external 'Setupapi.dll' name 'SetupDiCallClassInstaller';
  function UpdateDriverForPlugAndPlayDevices(hwndParent: THandle; HardwareId: Pchar; FullInfPath: Pchar; InstallFlags: DWORD; bRebootRequired: PBOOL ): BOOL; stdcall;external 'newdev.dll' name 'UpdateDriverForPlugAndPlayDevicesA';
  function SetupDiClassNameFromGuid(ClassGuid: PGUID; ClassName: PChar;ClassNameSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall;external 'Setupapi.dll' name 'SetupDiClassNameFromGuidA';

procedure SetPrivilege;
var
   TPPrev, TP: TTokenPrivileges;
   TokenHandle: THandle;
   dwRetLen: DWORD;
   lpLuid: TLargeInteger;
begin
   OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, TokenHandle);
  if (LookupPrivilegeValue(nil, 'SeDebugPrivilege', lpLuid)) then
  begin

     TP.PrivilegeCount := 1;
     TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
     TP.Privileges[0].Luid := lpLuid;
     AdjustTokenPrivileges(TokenHandle, False, TP, SizeOf(TPPrev), TPPrev, dwRetLen);
  end;
   CloseHandle(TokenHandle);
end;

function GetDeviceClassName(aGUID: TGUID): string;
var
    ClassName: PChar;
    ClassNameSize: DWORD;
begin
    ClassNameSize := 0;
    GetMem(ClassName, ClassNameSize);
    { 利用GUID返回设备类型名 }
   while not SetupDiClassNameFromGuid(@aGUID, ClassName, ClassNameSize,
      @ClassNameSize) do
   begin
     if
GetLastError() = ERROR_INSUFFICIENT_BUFFER then
     begin
       if
ClassName <> nil then FreeMem(ClassName);
        GetMem(ClassName, ClassNameSize);
     end else
        Break;
   end;
    Result := ClassName;
   if ClassName <> nil then FreeMem(ClassName);
end;

function StrPas(const Str: PChar): string;
begin
   Result := Str;
end;

function isinstalled(hardid:Pchar):bool;
var
    DevInfo: HDEVINFO;
    DeviceInfoData: SP_DEVINFO_DATA; {设备信息结构}
    i: Integer;
    DataT, Buffersize: DWORD;
    Buffer: pchar;
    index: Integer;
begin
    result:=false;
    DevInfo := SetupDiGetClassDevs(nil, 0, 0,DIGCF_PRESENT or DIGCF_ALLCLASSES);
   if DevInfo = nil then Exit;
    i := 0;
    Buffersize := 256;
    DeviceInfoData.cbSize := SizeOf(SP_DEVINFO_DATA);
    GetMem(Buffer, Buffersize);
    { 枚举设备信息 }
   while SetupDiEnumDeviceInfo(DevInfo, i, DeviceInfoData) do
   begin

     { 获取设备信息包括GUID和名称 }
     SetupDiGetDeviceRegistryProperty(DevInfo, DeviceInfoData,1, DataT, PByte(Buffer), Buffersize, DataT);
     Inc(i);
    if StrPas(hardid)= StrPas(Buffer) then
    begin

     result:=true;
     break;
    end;
   end;
   if Buffer <> nil then FreeMem(Buffer);
   if (GetLastError() <> NO_ERROR) and (GetLastError() <> ERROR_NO_MORE_ITEMS) then
      Exit;
    SetupDiDestroyDeviceInfoList(DevInfo);
end;

function InstallRootEnumeratedDriver(HardwareId, INFFile: Pchar; RebootRequired: PBOOL): DWORD;
var
   r: DWORD;
   DeviceInfoSet: HDEVINFO;
   DeviceInfoData: SP_DEVINFO_DATA;
   ClassGUID: TGUID;
   ClassName: array[0..MAX_CLASS_NAME_LEN - 1] of char;
label TheEnd;
begin
   r := 0;
   DeviceInfoSet := nil;

  if isinstalled(HardwareId) then  //如果已经有了服务,无需安装,直接加载即可
    if not(UpdateDriverForPlugAndPlayDevices(0, HardwareId, pchar(INFFile),INSTALLFLAG_FORCE,RebootRequired)) then
      begin

         r := GetLastError();SetLastError(r);
        goto TheEnd;
      end;
  if (not SetupDiGetINFClass(INFFile, ClassGUID, ClassName, sizeof(ClassName), nil)) then
  begin

     r := GetLastError();
    goto TheEnd;
  end;
   DeviceInfoSet := SetupDiCreateDeviceInfoList(@ClassGUID, 0);
  if (DWORD(DeviceInfoSet) = INVALID_HANDLE_VALUE) then
  begin

     r := GetLastError();
    goto TheEnd;
  end;
   DeviceInfoData.cbSize := sizeof(SP_DEVINFO_DATA);
  if (not SetupDiCreateDeviceInfo(DeviceInfoSet,ClassName,ClassGUID,nil,0,DICD_GENERATE_ID,@DeviceInfoData)) then
  begin

     r := GetLastError();
    goto TheEnd;
  end;
  if (not SetupDiSetDeviceRegistryProperty(DeviceInfoSet,DeviceInfoData,SPDRP_HARDWAREID,PBYTE(HardwareId),(lstrlen(HardwareId) + 1 + 1) * sizeof(CHAR))) then
  begin

     r := GetLastError();
    goto TheEnd;
  end;
  if (not SetupDiCallClassInstaller(DIF_REGISTERDEVICE,DeviceInfoSet,@DeviceInfoData)) then
  begin

     r := GetLastError();
    goto TheEnd;
  end;
  if not(UpdateDriverForPlugAndPlayDevices(0,HardwareId,INFFile,INSTALLFLAG_FORCE,RebootRequired)) then
  begin

     r := GetLastError();
    if (not SetupDiCallClassInstaller(DIF_REMOVE,DeviceInfoSet,@DeviceInfoData)) then   messagebox(0,pchar('出错6'),'aa',0);
     SetLastError(r);
    goto TheEnd;
  end;
  
TheEnd:
   SetupDiDestroyDeviceInfoList(DeviceInfoSet);
   Result := r;
end;

function ExtractFilePath(path: string): string;
var
   i: integer;
begin
   i := length(path);
  while i >= 1 do
  begin
    if
(path[i] = '\') or (path[i] = '/') or (path[i] = ':
') then
       break;
     dec(i);
   end;
   result := copy(path, 1, i);
end;

var
   Msg: TMsg;
   bReboot: BOOL ;
begin
   GetInputState();
   PostThreadMessage(GetCurrentThreadId(), 0, 0, 0);
   GetMessage(Msg, 0, 0, 0);
   //SetPrivilege;
   InstallRootEnumeratedDriver('
*OneDevice', pchar(extractfilepath(paramstr(0))+'One.inf
') ,@bReboot);
end.

读完这篇文章后,您心情如何?
0
0
0
0
0
0
0
0
本文网址: