本文整理自网络,侵删。
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.
来源:https://www.delphi6.com/article/sw21q7xj.html
相关阅读 >>
Delphi webbrowser通过遍历id查找元素是否存在
Delphi vcl 的 tpagecontrol 控件,实现对页签的拖动
更多相关阅读请进入《Delphi》频道 >>