Программная установка драйвера из Солдатова

Тема в разделе "WASM.BEGINNERS", создана пользователем Igi, 19 окт 2007.

  1. Igi

    Igi New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2005
    Сообщения:
    35
    Пытаюсь программно установить драйвер из первого примера Солдатова (есть inf и sys)

    Ниже код на Delphi. Здесь ошибка возвращается функцией SetupDiSetDeviceRegistryProperty
    Код (Text):
    1. unit setupinf;
    2.  
    3. interface
    4. uses Windows, kol, logging;
    5.   function InstallRootEnumeratedDriver(HardwareId, INFFile: Pchar; RebootRequired: PBOOL): DWORD;
    6.   function LoadSetupApi: Boolean;
    7.   procedure UnloadSetupApi;
    8.   function LoadNewDev: Boolean;
    9.   procedure UnloadNewDev;
    10.  
    11. implementation
    12. const
    13.   MAX_CLASS_NAME_LEN = 32;
    14.   DIGCF_PRESENT = $00000002;
    15.   DIGCF_ALLCLASSES = $00000004;
    16.  
    17.   SPDRP_DEVICEDESC = $00000000;  // DeviceDesc (R/W)
    18.   SPDRP_HARDWAREID = $00000001;  // HardwareID (R/W)
    19.   SPDRP_COMPATIBLEIDS = $00000002;  // CompatibleIDs (R/W)
    20.   SPDRP_UNUSED0 = $00000003;  // unused
    21.   SPDRP_SERVICE = $00000004;  // Service (R/W)
    22.   SPDRP_UNUSED1 = $00000005;  // unused
    23.   SPDRP_UNUSED2 = $00000006;  // unused
    24.   SPDRP_CLASS = $00000007;  // Class (R--tied to ClassGUID)
    25.   SPDRP_CLASSGUID = $00000008;  // ClassGUID (R/W)
    26.   SPDRP_DRIVER = $00000009;  // Driver (R/W)
    27.   SPDRP_CONFIGFLAGS = $0000000A;  // ConfigFlags (R/W)
    28.   SPDRP_MFG = $0000000B;  // Mfg (R/W)
    29.   SPDRP_FRIENDLYNAME = $0000000C;  // FriendlyName (R/W)
    30.   SPDRP_LOCATION_INFORMATION = $0000000D;  // LocationInformation (R/W)
    31.   SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = $0000000E;  // PhysicalDeviceObjectName (R)
    32.   SPDRP_CAPABILITIES = $0000000F;  // Capabilities (R)
    33.   SPDRP_UI_NUMBER = $00000010;  // UiNumber (R)
    34.   SPDRP_UPPERFILTERS = $00000011;  // UpperFilters (R/W)
    35.   SPDRP_LOWERFILTERS = $00000012;  // LowerFilters (R/W)
    36.   SPDRP_BUSTYPEGUID = $00000013;  // BusTypeGUID (R)
    37.   SPDRP_LEGACYBUSTYPE = $00000014;  // LegacyBusType (R)
    38.   SPDRP_BUSNUMBER = $00000015;  // BusNumber (R)
    39.   SPDRP_ENUMERATOR_NAME = $00000016;  // Enumerator Name (R)
    40.   SPDRP_SECURITY = $00000017;  // Security (R/W, binary form)
    41.   SPDRP_SECURITY_SDS = $00000018;  // Security (W, SDS form)
    42.   SPDRP_DEVTYPE = $00000019;  // Device Type (R/W)
    43.   SPDRP_EXCLUSIVE = $0000001A;  // Device is exclusive-access (R/W)
    44.   SPDRP_CHARACTERISTICS = $0000001B;  // Device Characteristics (R/W)
    45.  
    46.   DICD_GENERATE_ID = $00000001;
    47.   DIF_REGISTERDEVICE = $00000019;
    48.   DIF_REMOVE = $00000005;
    49.  
    50.   INSTALLFLAG_FORCE = $00000001;
    51. type
    52.   ULONG_PTR = DWORD;
    53.   DI_FUNCTION = UINT; // Function type for device installer
    54.  
    55.   //
    56.   // Define type for reference to device information set
    57.   //
    58.   HDEVINFO = Pointer;
    59.  
    60.   //
    61.   // Device information structure (references a device instance
    62.   // that is a member of a device information set)
    63.   //
    64.  
    65.   PSPDevInfoData = ^TSPDevInfoData;
    66.   SP_DEVINFO_DATA = packed record
    67.     cbSize: DWORD;
    68.     ClassGuid: TGUID;
    69.     DevInst: DWORD; // DEVINST handle
    70.     Reserved: ULONG_PTR;
    71.   end;
    72.  
    73.   {$EXTERNALSYM SP_DEVINFO_DATA}
    74.   TSPDevInfoData = SP_DEVINFO_DATA;
    75.  
    76.   TSetupDiGetClassDevsA = function(ClassGuid: PGUID; const Enumerator: PAnsiChar; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall;
    77.   TSetupDiGetClassDevs = TSetupDiGetClassDevsA;
    78.   TSetupDiEnumDeviceInfo = function(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; var DeviceInfoData: TSPDevInfoData): LongBool; stdcall;
    79.   TSetupDiGetDeviceRegistryPropertyA = function(DeviceInfoSet: HDEVINFO; const DeviceInfoData: TSPDevInfoData; Property_: DWORD; var PropertyRegDataType: DWORD; PropertyBuffer: PBYTE; PropertyBufferSize: DWORD; var RequiredSize: DWORD): LongBool; stdcall;
    80.   TSetupDiGetDeviceRegistryProperty = TSetupDiGetDeviceRegistryPropertyA;
    81.   TSetupDiDestroyDeviceInfoList = function(DeviceInfoSet: HDEVINFO): LongBool; stdcall;
    82.   TSetupDiGetINFClassA = function(const InfName: PAnsiChar; var ClassGuid: TGUID; ClassName: PAnsiChar; ClassNameSize: DWORD; RequiredSize: PDWORD): LongBool; stdcall;
    83.   TSetupDiGetINFClass = TSetupDiGetINFClassA;
    84.   TSetupDiCreateDeviceInfoList = function(ClassGuid: PGUID; hwndParent: HWND): HDEVINFO; stdcall;
    85.   TSetupDiCreateDeviceInfoA = function(DeviceInfoSet: HDEVINFO; const DeviceName: PAnsiChar; var ClassGuid: TGUID; const DeviceDescription: PAnsiChar; hwndParent: HWND; CreationFlags: DWORD; DeviceInfoData: PSPDevInfoData): LongBool; stdcall;
    86.   TSetupDiCreateDeviceInfo = TSetupDiCreateDeviceInfoA;
    87.   TSetupDiSetDeviceRegistryPropertyA = function(DeviceInfoSet: HDEVINFO; var DeviceInfoData: TSPDevInfoData; Property_: DWORD; const PropertyBuffer: PBYTE; PropertyBufferSize: DWORD): LongBool; stdcall;
    88.   TSetupDiSetDeviceRegistryProperty = TSetupDiSetDeviceRegistryPropertyA;
    89.   TSetupDiCallClassInstaller = function(InstallFunction: DI_FUNCTION; DeviceInfoSet: HDEVINFO; DeviceInfoData: PSPDevInfoData): LongBool; stdcall;
    90.   TUpdateDriverForPlugAndPlayDevicesA = function(hwndParent: THandle; HardwareId: Pchar; FullInfPath: Pchar; InstallFlags: DWORD; bRebootRequired: PBOOL ): BOOL; stdcall;
    91.  
    92. var
    93.   SetupDiGetClassDevs: TSetupDiGetClassDevs;
    94.   SetupDiEnumDeviceInfo: TSetupDiEnumDeviceInfo;
    95.   SetupDiGetDeviceRegistryProperty: TSetupDiGetDeviceRegistryProperty;
    96.   SetupDiDestroyDeviceInfoList: TSetupDiDestroyDeviceInfoList;
    97.   SetupDiGetINFClass: TSetupDiGetINFClass;
    98.   SetupDiCreateDeviceInfoList: TSetupDiCreateDeviceInfoList;
    99.   SetupDiCreateDeviceInfo: TSetupDiCreateDeviceInfo;
    100.   SetupDiSetDeviceRegistryProperty: TSetupDiSetDeviceRegistryProperty;
    101.   SetupDiCallClassInstaller: TSetupDiCallClassInstaller;
    102.   UpdateDriverForPlugAndPlayDevices: TUpdateDriverForPlugAndPlayDevicesA;
    103. const
    104.   SetupApiModuleName = 'SetupApi.dll';
    105.   NewDevModuleName = 'newdev.dll';
    106. var
    107.   SetupApiLib: THandle = 0;
    108.   NewDevLib: THandle = 0;
    109.  
    110. function LoadSetupApi: Boolean;
    111. begin
    112.   Result := False;
    113.   if SetupApiLib = 0 then
    114.     SetupApiLib := LoadLibrary(SetupApiModuleName);
    115.   if SetupApiLib = 0 then Exit;
    116.   try
    117.     @SetupDiGetClassDevs := GetProcAddress(SetupApiLib, 'SetupDiGetClassDevsA');
    118.     @SetupDiEnumDeviceInfo := GetProcAddress(SetupApiLib, 'SetupDiEnumDeviceInfo');
    119.     @SetupDiGetDeviceRegistryProperty := GetProcAddress(SetupApiLib, 'SetupDiGetDeviceRegistryPropertyA');
    120.     @SetupDiDestroyDeviceInfoList := GetProcAddress(SetupApiLib, 'SetupDiDestroyDeviceInfoList');
    121.     @SetupDiGetINFClass := GetProcAddress(SetupApiLib, 'SetupDiGetINFClassA');
    122.     @SetupDiCreateDeviceInfoList := GetProcAddress(SetupApiLib, 'SetupDiCreateDeviceInfoList');
    123.     @SetupDiCreateDeviceInfo := GetProcAddress(SetupApiLib, 'SetupDiCreateDeviceInfoA');
    124.     @SetupDiSetDeviceRegistryProperty := GetProcAddress(SetupApiLib, 'SetupDiSetDeviceRegistryPropertyA');
    125.     @SetupDiCallClassInstaller := GetProcAddress(SetupApiLib, 'SetupDiCallClassInstaller');
    126.   except
    127.     if SetupApiLib <> 0 then FreeLibrary(SetupApiLib);
    128.     Exit;
    129.   end;
    130.   Result := True;
    131. end;
    132.  
    133. procedure UnloadSetupApi;
    134. begin
    135.   if SetupApiLib <> 0 then FreeLibrary(SetupApiLib);
    136.   @SetupDiGetClassDevs := nil;
    137.   @SetupDiEnumDeviceInfo := nil;
    138.   @SetupDiGetDeviceRegistryProperty := nil;
    139.   @SetupDiDestroyDeviceInfoList := nil;
    140.   @SetupDiGetINFClass := nil;
    141.   @SetupDiCreateDeviceInfoList := nil;
    142.   @SetupDiCreateDeviceInfo := nil;
    143.   @SetupDiSetDeviceRegistryProperty := nil;
    144.   @SetupDiCallClassInstaller := nil;
    145. end;
    146.  
    147. function LoadNewDev: Boolean;
    148. begin
    149.   Result := False;
    150.   if NewDevLib = 0 then
    151.     NewDevLib := LoadLibrary(NewDevModuleName);
    152.   if NewDevLib = 0 then Exit;
    153.  
    154.   try
    155.     @UpdateDriverForPlugAndPlayDevices := GetProcAddress(NewDevLib, 'UpdateDriverForPlugAndPlayDevicesA');
    156.   except
    157.     if NewDevLib <> 0 then FreeLibrary(NewDevLib);
    158.     Exit;
    159.   end;
    160. end;
    161.  
    162. procedure UnloadNewDev;
    163. begin
    164.   if NewDevLib <> 0 then FreeLibrary(NewDevLib);
    165.   @UpdateDriverForPlugAndPlayDevices := nil;
    166. end;
    167.  
    168. function InstallRootEnumeratedDriver(HardwareId, INFFile: Pchar; RebootRequired: PBOOL): DWORD;
    169. var
    170.   r: DWORD;
    171.   DeviceInfoSet: HDEVINFO;
    172.   DeviceInfoData: SP_DEVINFO_DATA;
    173.   ClassGUID: TGUID;
    174.   ClassName: array[0..MAX_CLASS_NAME_LEN - 1] of char;
    175. label TheEnd;
    176. begin
    177.   r := 0;
    178.   DeviceInfoSet := nil;
    179.  
    180.   // ïîëó÷åíèå èìåíè è guid êëàññà óñòðîéñòâà èç inf-ôàéëà
    181.   if (not SetupDiGetINFClass(INFFile, ClassGUID, ClassName, sizeof(ClassName), nil)) then
    182.     begin
    183.       r := GetLastError();
    184.       goto TheEnd;
    185.     end;
    186.  
    187.   // ñîçäàíèå ïóñòîãî íàáîðà èíôîðìàöèè îá óñòðîéñòâå (ñïèñîê ýëåìåíòîâ)
    188.   DeviceInfoSet := SetupDiCreateDeviceInfoList(@ClassGUID, 0);
    189.   if (DWORD(DeviceInfoSet) = INVALID_HANDLE_VALUE) then
    190.     begin
    191.       LogFile('SetupDiCreateDeviceInfoList');
    192.       r := GetLastError();
    193.       goto TheEnd;
    194.     end;
    195.  
    196.   // ñîçäàíèå íîâîãî ýëåìåíòà (õýíäë óñòðîéñòâà è ñïèñîê âñåõ èíòåðôåéñîâ
    197.   // äëÿ íåãî), èñïîëüçóÿ èìÿ è GUID óñòðîéñòâà
    198.   DeviceInfoData.cbSize := sizeof(SP_DEVINFO_DATA);
    199.   if (not SetupDiCreateDeviceInfo(DeviceInfoSet,
    200.                                   ClassName,
    201.                                   ClassGUID,
    202.                                   nil,
    203.                                   0,
    204.                                   DICD_GENERATE_ID,
    205.                                   @DeviceInfoData)) then
    206.     begin
    207.       LogFile('SetupDiCreateDeviceInfo');
    208.       r := GetLastError();
    209.       goto TheEnd;
    210.     end;
    211.  
    212.   // äîáàâëåíèå â ðååñòð èíôîðìàöèè îá óñòðîéñòâå ïî åãî ñâîéñòâó HardwareID
    213.   if (not SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
    214.                                            DeviceInfoData,
    215.                                            SPDRP_HARDWAREID,
    216.                                            PBYTE(HardwareId),
    217.                                            (lstrlen(HardwareId) + 1 + 1) * sizeof(CHAR))) then
    218.     begin
    219.       r := GetLastError();
    220.       LogFile('SetupDiSetDeviceRegistryProperty: %s', [SysErrorMessage(r)]);
    221.       goto TheEnd;
    222.     end;
    223.  
    224.   // Transform the registry element into an actual devnode in the PnP HW tree.
    225.   if (not SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
    226.                                     DeviceInfoSet,
    227.                                     @DeviceInfoData)) then
    228.     begin
    229.       LogFile('SetupDiCallClassInstaller');
    230.       r := GetLastError();
    231.       goto TheEnd;
    232.     end;
    233.  
    234.   // The element is now registered. We must explicitly remove the
    235.   // device using DIF_REMOVE, if we encounter any failure from now on.
    236.  
    237.   // Install the Driver.
    238.   if (not UpdateDriverForPlugAndPlayDevices(0,
    239.                                             HardwareId,
    240.                                             INFFile,
    241.                                             INSTALLFLAG_FORCE,
    242.                                             RebootRequired)) then
    243.     begin
    244.       r := GetLastError();
    245.       LogFile('UpdateDriverForPlugAndPlayDevices: %s', [SysErrorMessage(r)]);
    246.       if (not SetupDiCallClassInstaller(
    247.                                 DIF_REMOVE,
    248.                                 DeviceInfoSet,
    249.                                 @DeviceInfoData)) then
    250.         begin
    251.           LogFile('SetupDiCallClassInstaller: %s', [SysErrorMessage(GetLastError())]);
    252.         end;
    253.        SetLastError(r);
    254.       goto TheEnd;
    255.     end;
    256.  
    257. TheEnd:
    258.   SetupDiDestroyDeviceInfoList(DeviceInfoSet);
    259.   Result := r;
    260. end;
    261.  
    262. end.
    А вот сама установка:
    Код (Text):
    1. var
    2.   bReboot: BOOL = true;
    3. ....
    4.   LoadSetupApi();
    5.   LoadNewDev;
    6.   InstallRootEnumeratedDriver('Example', 'C:\test\Example.inf' ,@bReboot);
    7.   UnloadNewDev;
    8.   UnloadSetupApi();
    C драйверами только начал разбираться. Помогите разобраться с примером...
     
  2. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    Ну зачем вываливать тут эту груду кода? Надо маленький кусочек, что именно Вам не понятно или где ошибочный вызов функции. А тут люди занятые все, и некогда им читать горы делфийского кода, который должен быть написан на сях.
     
  3. Igi

    Igi New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2005
    Сообщения:
    35
    Все, разобрался. Это оказывается inf файл был какой-то не такой. devcon тоже не мог его установить, хотя Мастер нового оборудования нормально ставит. Сгенерировал новый программой GenInf и все стало нормально.

    И еще исправил
    SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
    DeviceInfoData,
    SPDRP_HARDWAREID,
    PBYTE(HardwareId),
    (lstrlen(HardwareId) + 1 + 1) * sizeof(CHAR))

    на

    SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
    DeviceInfoData,
    SPDRP_HARDWAREID,
    PBYTE(HardwareId),
    (lstrlen(HardwareId) + 1 + 1) * sizeof(CHAR) * 2)