unit unit 1;
連接
使用
窗口、消息、系統工具、變體、類、圖形、控件、表單,
Dialogs,StdCtrls { SetupApi }。
常數
hardware ids =‘v keyboard‘;
DeviceName =“虛擬鍵盤“;
MAX _ CLASS _ NAME _ LEN = 128;
DIF _ REMOVE = $ 00000005;
install flag _ FORCE = $ 00000001;
sp DRP _ hardware id = $ 00000001;
DIF _註冊設備= $ 00000019;
DIGCF _ PRESENT = $ 0002
DIGCF _ ALLCLASSES = $ 0004
DIGCF _ PROFILE = $ 00000008
DICD _ GENERATE _ ID = $ 00000001;
類型
ULONG _ PTR = DWORD
DI _ FUNCTION = UINT
HDEVINFO =指針;
pspdevinfodata = ^tspdevinfodata;
SP_DEVINFO_DATA =打包記錄
cbSize:DWORD;
class guid:TGUID;
迪文斯特:德沃德;
保留:ULONG _ PTR
結束;
{$EXTERNALSYM SP_DEVINFO_DATA}
TSPDetsigCmpProc = function(device infoset:HDEVINFO;NewDeviceData,
ExistingDeviceData:PSPDevInfoData;compare context:Pointer):DWORD;stdcall
TSPDevInfoData = SP _ DEVINFO _ DATA;
t form 1 = class(t form)
button 1:t button;
過程按鈕1Click(發件人:to object);
私人的
{私有聲明}
公眾的
{公開聲明}
結束;
定義變量
form 1:t form 1;
履行
{$R *。dfm}
定義變量
keyboard class:TGUID =‘{ 4d 36 e 96 b-E325-11CE-bfc 1-08002 be 10318 }‘;
函數SetupDiGetClassDevs(class guid:PGUID;const枚舉器:PAnsiCharHWND parent:HWND;flags:DWORD):HDEVINFO;stdcall外部“Setupapi.dll”名稱為“SetupDiGetClassDevsA”;
函數SetupDiEnumDeviceInfo(DeviceInfoSet:HDEVINFO;member index:DWORD;var DeviceInfoData:TSPDevInfoData):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiEnumDeviceInfo”;
函數SetupDiGetDeviceRegistryProperty(device infoset:HDEVINFO;const device info data:TSPDevInfoData;property _:DWORD;var PropertyRegDataType:DWORD;property buffer:PBYTE;property buffer size:DWORD;var required size:DWORD):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiGetDeviceRegistryPropertyA”;
函數SetupDiDestroyDeviceInfoList(device infoset:HDEVINFO):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiDestroyDeviceInfoList”;
函數SetupDiGetINFClass(const InfName:PAnsiChar;var class guid:TGUID;類名:PAnsiCharclass name size:DWORD;required size:PD word):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiGetINFClassA”;
函數SetupDiCreateDeviceInfoList(class guid:PGUID;HWND parent:HWND):HDEVINFO;stdcall外部“Setupapi.dll”名稱為“SetupDiCreateDeviceInfoList”;
函數SetupDiCreateDeviceInfo(device info set:HDEVINFO;const device name:PAnsiChar;var class guid:TGUID;const device description:PAnsiChar;HWND parent:HWND;creation flags:DWORD;DeviceInfoData:PSPDevInfoData):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiCreateDeviceInfoA”;
函數SetupDiSetDeviceRegistryProperty(device infoset:HDEVINFO;var device info data:TSPDevInfoData;property _:DWORD;const property buffer:PBYTE;PropertyBufferSize:DWORD):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiSetDeviceRegistryPropertyA”;
函數setup dicallclassinstaller(install FUNCTION:DI _ FUNCTION;device infoset:HDEVINFO;DeviceInfoData:PSPDevInfoData):long bool;stdcall外部“Setupapi.dll”名稱為“setup dicallclassinstaller”;
函數UpdateDriverForPlugAndPlayDevices(hwnd parent:THandle;hardware id:Pchar;full infpath:Pchar;install flags:DWORD;breboot required:PBOOL):BOOL;stdcall外部“newdev.dll”名稱為“UpdateDriverForPlugAndPlayDevicesA”;
函數setup diclassnamefromguid(class guid:PGUID;類名:PCharclass name size:DWORD;required size:PD word):BOOL;stdcall外部“Setupapi.dll”名稱為“SetupDiClassNameFromGuidA”;
函數SetupDiRegisterDeviceInfo(device info set:HDEVINFO;var device info data:TSPDevInfoData;標誌:DWORDcompare proc:TSPDetSigCmpProc;CompareContext:指針;DupDeviceInfoData:PSPDevInfoData):long bool;stdcall外部“Setupapi.dll”名稱為“SetupDiRegisterDeviceInfo”;
函數display msg(msg:string):整數;
開始
結果:= MessageBox(0,pchar(msg),message,MB _ OK);
結束;
函數FindExistingDevice():boolean;
定義變量
device infoset:HDEVINFO;
找到:布爾型;
device info DATA:SP _ DEVINFO _ DATA;
我:DWord;
數據:DWord;
buf:pchar;
buffsize:整數;
開始
device infoset:= SetupDiGetClassDevs(nil,0,0,(DIGCF_ALLCLASSES或DIGCF_PRESENT
或dig cf _ PROFILE));
如果DeviceInfoSet = nil,則
退出;
發現:= false
device info DATA . cbsize:= sizeof(SP _ DEVINFO _ DATA);
I:= 0;
buff size:= 10240;
get mem(buf,buff size);
而SetupDiEnumDeviceInfo(DeviceInfoSet,I,DeviceInfoData)會
開始
inc(壹);
DataT:= 0;
如果不是SetupDiGetDeviceRegistryProperty(DeviceInfoSet,DeviceInfoData,
SPDRP_HARDWAREID,
DataT,
PByte(buf),
buffsize,
DataT)然後
開始
繼續;
結束;
如果hardware ids = strpas(buf),則
開始
發現:= true
打破;
結束;
結束;
如果buf & lt& gt那就零
freemem(buf);
SetupDiDestroyDeviceInfoList(device infoset);
結果:=找到;
結束;
程序t表格1。Button1Click(發件人:to object);
定義變量
文件名,驅動器,路徑,infile,sysfile:string。
device infoset:HDEVINFO;
class guid:TGUID;
dev:SP _ DEVINFO _ DATA;
現狀:隆布爾;
reboot required:long bool;
呃:DWord;
開始
如果找到現有設備,則
開始
DisplayMsg(“虛擬鍵盤已安裝”);
退出;
結束;
文件名:=應用程序。ExeName
Path := ExtractFilePath(文件名);
infile:= path+‘keyfdo . INF‘;
sysfile:= path+‘vkeyfdo . sys‘;
如果不存在文件(infile),則
開始
display msg(‘找不到。INF文件’);
退出;
結束;
如果不存在文件(sysfile),則
開始
display msg(‘找不到。sys文件’);
退出;
結束;
device infoset:= SetupDiCreateDeviceInfoList(@ keyboard class,0);
if(DWORD(device infoset)= INVALID _ HANDLE _ VALUE)然後
開始
DisplayMsg(“無法獲取設備信息列表”);
退出;
結束;
dev . cbsize:= sizeof(SP _ DEVINFO _ DATA);
狀態:= SetupDiCreateDeviceInfo
(設備信息集,pchar(設備名稱),
KeyboardClass,pchar(device name),0,DICD生成ID,@ dev);
如果不是狀態,則
開始
DisplayMsg(“無法創建設備”);
退出;
結束;
status:= SetupDiRegisterDeviceInfo(DeviceInfoSet,dev,0,nil,nil,nil);
如果不是狀態,則
開始
DisplayMsg(“無法註冊設備”);
退出;
結束;
狀態:= SetupDiSetDeviceRegistryProperty
(DeviceInfoSet,dev,SPDRP_HARDWAREID,Pbyte(PChar(hardware id)),
(lstrlen(hardware ids)+1+1)* sizeof(char);
如果不是狀態,則
開始
err:= GetLastError();
display msg(‘無法設置設備硬件id‘+inttostr(err));
退出;
結束;
SetupDiDestroyDeviceInfoList(device infoset);
狀態:= UpdateDriverForPlugAndPlayDevices(0,
HardwareIDs,pchar(infile),0,@ reboo required);
如果不是狀態,則
開始
err:= GetLastError();
display msg(‘無法更新設備硬件id‘+inttostr(err));
status:= SetupDiCallClassInstaller(DIF _ REMOVE,設備信息集,@ dev);
如果不是狀態,則
開始
DisplayMsg(“無法安裝設備硬件id”);
退出;
結束;
結束;
結束;
結束。