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返回设备类型名 } whilenot SetupDiClassNameFromGuid(@aGUID, ClassName, ClassNameSize, @ClassNameSize) do begin if GetLastError() = ERROR_INSUFFICIENT_BUFFER then begin if ClassName <> nilthen FreeMem(ClassName); GetMem(ClassName, ClassNameSize); endelse Break; end; Result := ClassName; if ClassName <> nilthen 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 = nilthen 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 <> nilthen 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] ofchar; label TheEnd; begin r := 0; DeviceInfoSet := nil;
if isinstalled(HardwareId) then//如果已经有了服务,无需安装,直接加载即可 ifnot(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; ifnot(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;