Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как программно обновить оборудование? как в "Диспетчере устройств" 
:(
    Опции темы
Ciber SLasH
Дата 26.10.2005, 04:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 1
Всего: 67



Вот хотел было сделать программное обновление оборудования, нападобие как в "Диспетчере устройств".
Нашёл код в MSDN как это делается и перевёл это на Delphi (пришлось качнуть ещё кой-какие модули):
Код

function ScanForHardwareChange: Boolean;
var
  dvInst: DEVINST;
  status: CONFIGRET;
begin
  Result := true;
  status := CM_Locate_DevNode(dvInst, nil, CM_LOCATE_DEVNODE_NORMAL);
  if status <> CR_SUCCESS then
  begin
    Result := false;
    ShowMessage('CM_Locate_DevNode failed !!');
    Exit
  end;
  status := CM_Reenumerate_DevNode(dvInst, 0);
  if status <> CR_SUCCESS then
  begin
    Result := false;
    ShowMessage('CM_Reenumerate_DevNode failed !!')
  end
end;

но при вызове этой функции вылазит Access violation. Пытался включить привелегию "SeDebugPrivilege", но это не помогло.

Как же реализовать эту задачу?

Need help !!

Это сообщение отредактировал(а) Ciber SLasH - 26.10.2005, 15:27

Присоединённый файл ( Кол-во скачиваний: 29 )
Присоединённый файл  modules.rar 50,67 Kb
PM   Вверх
_hunter
Дата 26.10.2005, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 9
Всего: 98



и где оно выдазит?
+ есть у меня подозрение что замена DEVINST DWORD-ом несколько опрометчива...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Ciber SLasH
Дата 26.10.2005, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 1
Всего: 67



Исправил DWORD на DEVINST, хотя в модуле CfgMgr32.pas этот тип определён как DWORD.

А вылетает когда пытается выполнить 7-ю строку функции.
PM   Вверх
Ciber SLasH
Дата 26.10.2005, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 1
Всего: 67



Всё... я разобрался... теперь не нужно вручную каждый раз при необходимости вылезть в сеть обновлять оборудования ищя модем, который при загрузке винды был вырублен.

Вот полный код программы:
Код

program Project1;

uses Windows, Messages, CfgMgr32_Rip;

{$R *.res}

{--- Обновление оборудования (как в "Диспетчере устройств") ---}
function ScanForHardwareChange: Boolean;
const
  DLLName = 'cfgmgr32.dll';
  CMLocateDevNode_Name = 'CM_Locate_DevNodeA';
  CMReenumerateDevNode_Name = 'CM_Reenumerate_DevNode';
type
  { Получение дескриптора устройства к узлу устройства, который связан с
    указанным идентификатором устройства на локальной машине }
  CM_Locate_DevNode_Func = function (var dnDevInst: DEVINST;
    pDeviceID: DEVINSTID; ulFlags: ULONG): CONFIGRET; stdcall;
  { Перечисление устройств, идентифицированных указанным узлом устройства и
    всеми его детьми }
  CM_Reenumerate_DevNode_Func = function (dnDevInst: DEVINST;
    ulFlags: ULONG): CONFIGRET; stdcall;
var
  dvInst: DEVINST;    // дескриптор вызываемого устройства
  status: CONFIGRET;  // статус
  CMLocateDevNode: CM_Locate_DevNode_Func;
  CMReenumerateDevNode: CM_Reenumerate_DevNode_Func;
  hDLL: THandle;
begin
  Result := false;
  hDLL := LoadLibrary(DLLName);
  if hDLL = INVALID_HANDLE_VALUE then
  begin
    MessageBox(0, PChar('Не удалось загрузить библиотеку: ' + DLLName),
               'Error (Project1::ScanForHardwareChange -> LoadLibrary)',
               MB_OK + MB_ICONERROR);
    Exit
  end;
  // CMLocateDevNode
  try
    @CMLocateDevNode := GetProcAddress(hDLL, CMLocateDevNode_Name);
    if @CMLocateDevNode <> nil then
      status := CMLocateDevNode(dvInst, nil, CM_LOCATE_DEVNODE_NORMAL)
    else
    begin
      MessageBox(0, 'Неверно указано имя функции (DLLName) в "GetProcAddress(hDLL, DLLName)" !!',
                 'Error (Project1::ScanForHardwareChange -> GetProcAddress)',
                 MB_OK + MB_ICONERROR);
      FreeLibrary(hDLL);
      Exit
    end
  except
    MessageBox(0, PChar('Не удалось получить адресс функции: ' + CMLocateDevNode_Name),
               'Error (Project1::ScanForHardwareChange -> GetProcAddress)',
               MB_OK + MB_ICONERROR);
    FreeLibrary(hDLL);
    Exit
  end;
  if status <> CR_SUCCESS then
  begin
    MessageBox(0, 'Функция "CMLocateDevNode" выполнилась с ошибкой !!',
               'Error (Project1::ScanForHardwareChange -> CMLocateDevNode)',
               MB_OK + MB_ICONERROR);
    Exit
  end;
  // CMReenumerateDevNode
  try
    @CMReenumerateDevNode := GetProcAddress(hDLL, CMReenumerateDevNode_Name);
    if @CMReenumerateDevNode <> nil then
      status := CMReenumerateDevNode(dvInst, 0)
    else
    begin
      MessageBox(0, 'Неверно указано имя функции (DLLName) в "GetProcAddress(hDLL, DLLName)" !!',
                 'Error (Project1::ScanForHardwareChange -> GetProcAddress)',
                 MB_OK + MB_ICONERROR);
      FreeLibrary(hDLL);
      Exit
    end
  except
    MessageBox(0, PChar('Не удалось получить адресс функции: ' + CMReenumerateDevNode_Name),
               'Error (Project1::ScanForHardwareChange -> GetProcAddress)',
               MB_OK + MB_ICONERROR);
    FreeLibrary(hDLL);
    Exit
  end;
  if status <> CR_SUCCESS then
    MessageBox(0, 'Функция "CMReenumerateDevNode" выполнилась с ошибкой !!',
               'Error (Project1::ScanForHardwareChange -> CMReenumerateDevNode)',
               MB_OK + MB_ICONERROR)
  else
    Result := true;
  FreeLibrary(hDLL)
end;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
begin
  if MessageBox(0, 'Обновить оборудование ?',
                'Confirm (Project1)',
                MB_YESNO + MB_ICONQUESTION) = IDYES
  then
    if ScanForHardwareChange then
      MessageBox(0, 'Всё ништяк, оборудование обновлено !!',
                 'Info (Project1 -> ScanForHardwareChange)',
                 MB_OK + MB_ICONINFORMATION)
    else
      MessageBox(0, 'Нифига не получилось !!',
                 'Error (Project1 -> ScanForHardwareChange)',
                 MB_OK + MB_ICONERROR)
end.

а вот порипанный модуль (все остальные теперь не нужны для этого действия):
Код

unit CfgMgr32_Rip;

interface

uses Windows;

const
//------------------------------------------------------------------------------
// Flags for CM_Locate_DevNode
//------------------------------------------------------------------------------
  CM_LOCATE_DEVNODE_NORMAL       = $00000000;
  {$EXTERNALSYM CM_LOCATE_DEVNODE_NORMAL}
  CM_LOCATE_DEVNODE_PHANTOM      = $00000001;
  {$EXTERNALSYM CM_LOCATE_DEVNODE_PHANTOM}
  CM_LOCATE_DEVNODE_CANCELREMOVE = $00000002;
  {$EXTERNALSYM CM_LOCATE_DEVNODE_CANCELREMOVE}
  CM_LOCATE_DEVNODE_NOVALIDATION = $00000004;
  {$EXTERNALSYM CM_LOCATE_DEVNODE_NOVALIDATION}
  CM_LOCATE_DEVNODE_BITS         = $00000007;
  {$EXTERNALSYM CM_LOCATE_DEVNODE_BITS}

  CM_LOCATE_DEVINST_NORMAL       = CM_LOCATE_DEVNODE_NORMAL;
  {$EXTERNALSYM CM_LOCATE_DEVINST_NORMAL}
  CM_LOCATE_DEVINST_PHANTOM      = CM_LOCATE_DEVNODE_PHANTOM;
  {$EXTERNALSYM CM_LOCATE_DEVINST_PHANTOM}
  CM_LOCATE_DEVINST_CANCELREMOVE = CM_LOCATE_DEVNODE_CANCELREMOVE;
  {$EXTERNALSYM CM_LOCATE_DEVINST_CANCELREMOVE}
  CM_LOCATE_DEVINST_NOVALIDATION = CM_LOCATE_DEVNODE_NOVALIDATION;
  {$EXTERNALSYM CM_LOCATE_DEVINST_NOVALIDATION}
  CM_LOCATE_DEVINST_BITS         = CM_LOCATE_DEVNODE_BITS;
  {$EXTERNALSYM CM_LOCATE_DEVINST_BITS}

//------------------------------------------------------------------------------
// Configuration Manager return status codes
//------------------------------------------------------------------------------
  CR_SUCCESS                  = $00000000;
  {$EXTERNALSYM CR_SUCCESS}
  CR_DEFAULT                  = $00000001;
  {$EXTERNALSYM CR_DEFAULT}
  CR_OUT_OF_MEMORY            = $00000002;
  {$EXTERNALSYM CR_OUT_OF_MEMORY}
  CR_INVALID_POINTER          = $00000003;
  {$EXTERNALSYM CR_INVALID_POINTER}
  CR_INVALID_FLAG             = $00000004;
  {$EXTERNALSYM CR_INVALID_FLAG}
  CR_INVALID_DEVNODE          = $00000005;
  {$EXTERNALSYM CR_INVALID_DEVNODE}
  CR_INVALID_DEVINST          = CR_INVALID_DEVNODE;
  {$EXTERNALSYM CR_INVALID_DEVINST}
  CR_INVALID_RES_DES          = $00000006;
  {$EXTERNALSYM CR_INVALID_RES_DES}
  CR_INVALID_LOG_CONF         = $00000007;
  {$EXTERNALSYM CR_INVALID_LOG_CONF}
  CR_INVALID_ARBITRATOR       = $00000008;
  {$EXTERNALSYM CR_INVALID_ARBITRATOR}
  CR_INVALID_NODELIST         = $00000009;
  {$EXTERNALSYM CR_INVALID_NODELIST}
  CR_DEVNODE_HAS_REQS         = $0000000A;
  {$EXTERNALSYM CR_DEVNODE_HAS_REQS}
  CR_DEVINST_HAS_REQS         = CR_DEVNODE_HAS_REQS;
  {$EXTERNALSYM CR_DEVINST_HAS_REQS}
  CR_INVALID_RESOURCEID       = $0000000B;
  {$EXTERNALSYM CR_INVALID_RESOURCEID}
  CR_DLVXD_NOT_FOUND          = $0000000C;   // WIN 95 ONLY
  {$EXTERNALSYM CR_DLVXD_NOT_FOUND}
  CR_NO_SUCH_DEVNODE          = $0000000D;
  {$EXTERNALSYM CR_NO_SUCH_DEVNODE}
  CR_NO_SUCH_DEVINST          = CR_NO_SUCH_DEVNODE;
  {$EXTERNALSYM CR_NO_SUCH_DEVINST}
  CR_NO_MORE_LOG_CONF         = $0000000E;
  {$EXTERNALSYM CR_NO_MORE_LOG_CONF}
  CR_NO_MORE_RES_DES          = $0000000F;
  {$EXTERNALSYM CR_NO_MORE_RES_DES}
  CR_ALREADY_SUCH_DEVNODE     = $00000010;
  {$EXTERNALSYM CR_ALREADY_SUCH_DEVNODE}
  CR_ALREADY_SUCH_DEVINST     = CR_ALREADY_SUCH_DEVNODE;
  {$EXTERNALSYM CR_ALREADY_SUCH_DEVINST}
  CR_INVALID_RANGE_LIST       = $00000011;
  {$EXTERNALSYM CR_INVALID_RANGE_LIST}
  CR_INVALID_RANGE            = $00000012;
  {$EXTERNALSYM CR_INVALID_RANGE}
  CR_FAILURE                  = $00000013;
  {$EXTERNALSYM CR_FAILURE}
  CR_NO_SUCH_LOGICAL_DEV      = $00000014;
  {$EXTERNALSYM CR_NO_SUCH_LOGICAL_DEV}
  CR_CREATE_BLOCKED           = $00000015;
  {$EXTERNALSYM CR_CREATE_BLOCKED}
  CR_NOT_SYSTEM_VM            = $00000016;   // WIN 95 ONLY
  {$EXTERNALSYM CR_NOT_SYSTEM_VM}
  CR_REMOVE_VETOED            = $00000017;
  {$EXTERNALSYM CR_REMOVE_VETOED}
  CR_APM_VETOED               = $00000018;
  {$EXTERNALSYM CR_APM_VETOED}
  CR_INVALID_LOAD_TYPE        = $00000019;
  {$EXTERNALSYM CR_INVALID_LOAD_TYPE}
  CR_BUFFER_SMALL             = $0000001A;
  {$EXTERNALSYM CR_BUFFER_SMALL}
  CR_NO_ARBITRATOR            = $0000001B;
  {$EXTERNALSYM CR_NO_ARBITRATOR}
  CR_NO_REGISTRY_HANDLE       = $0000001C;
  {$EXTERNALSYM CR_NO_REGISTRY_HANDLE}
  CR_REGISTRY_ERROR           = $0000001D;
  {$EXTERNALSYM CR_REGISTRY_ERROR}
  CR_INVALID_DEVICE_ID        = $0000001E;
  {$EXTERNALSYM CR_INVALID_DEVICE_ID}
  CR_INVALID_DATA             = $0000001F;
  {$EXTERNALSYM CR_INVALID_DATA}
  CR_INVALID_API              = $00000020;
  {$EXTERNALSYM CR_INVALID_API}
  CR_DEVLOADER_NOT_READY      = $00000021;
  {$EXTERNALSYM CR_DEVLOADER_NOT_READY}
  CR_NEED_RESTART             = $00000022;
  {$EXTERNALSYM CR_NEED_RESTART}
  CR_NO_MORE_HW_PROFILES      = $00000023;
  {$EXTERNALSYM CR_NO_MORE_HW_PROFILES}
  CR_DEVICE_NOT_THERE         = $00000024;
  {$EXTERNALSYM CR_DEVICE_NOT_THERE}
  CR_NO_SUCH_VALUE            = $00000025;
  {$EXTERNALSYM CR_NO_SUCH_VALUE}
  CR_WRONG_TYPE               = $00000026;
  {$EXTERNALSYM CR_WRONG_TYPE}
  CR_INVALID_PRIORITY         = $00000027;
  {$EXTERNALSYM CR_INVALID_PRIORITY}
  CR_NOT_DISABLEABLE          = $00000028;
  {$EXTERNALSYM CR_NOT_DISABLEABLE}
  CR_FREE_RESOURCES           = $00000029;
  {$EXTERNALSYM CR_FREE_RESOURCES}
  CR_QUERY_VETOED             = $0000002A;
  {$EXTERNALSYM CR_QUERY_VETOED}
  CR_CANT_SHARE_IRQ           = $0000002B;
  {$EXTERNALSYM CR_CANT_SHARE_IRQ}
  CR_NO_DEPENDENT             = $0000002C;
  {$EXTERNALSYM CR_NO_DEPENDENT}
  CR_SAME_RESOURCES           = $0000002D;
  {$EXTERNALSYM CR_SAME_RESOURCES}
  CR_NO_SUCH_REGISTRY_KEY     = $0000002E;
  {$EXTERNALSYM CR_NO_SUCH_REGISTRY_KEY}
  CR_INVALID_MACHINENAME      = $0000002F;   // NT ONLY
  {$EXTERNALSYM CR_INVALID_MACHINENAME}
  CR_REMOTE_COMM_FAILURE      = $00000030;   // NT ONLY
  {$EXTERNALSYM CR_REMOTE_COMM_FAILURE}
  CR_MACHINE_UNAVAILABLE      = $00000031;   // NT ONLY
  {$EXTERNALSYM CR_MACHINE_UNAVAILABLE}
  CR_NO_CM_SERVICES           = $00000032;   // NT ONLY
  {$EXTERNALSYM CR_NO_CM_SERVICES}
  CR_ACCESS_DENIED            = $00000033;   // NT ONLY
  {$EXTERNALSYM CR_ACCESS_DENIED}
  CR_CALL_NOT_IMPLEMENTED     = $00000034;
  {$EXTERNALSYM CR_CALL_NOT_IMPLEMENTED}
  CR_INVALID_PROPERTY         = $00000035;
  {$EXTERNALSYM CR_INVALID_PROPERTY}
  CR_DEVICE_INTERFACE_ACTIVE  = $00000036;
  {$EXTERNALSYM CR_DEVICE_INTERFACE_ACTIVE}
  CR_NO_SUCH_DEVICE_INTERFACE = $00000037;
  {$EXTERNALSYM CR_NO_SUCH_DEVICE_INTERFACE}
  CR_INVALID_REFERENCE_STRING = $00000038;
  {$EXTERNALSYM CR_INVALID_REFERENCE_STRING}
  CR_INVALID_CONFLICT_LIST    = $00000039;
  {$EXTERNALSYM CR_INVALID_CONFLICT_LIST}
  CR_INVALID_INDEX            = $0000003A;
  {$EXTERNALSYM CR_INVALID_INDEX}
  CR_INVALID_STRUCTURE_SIZE   = $0000003B;
  {$EXTERNALSYM CR_INVALID_STRUCTURE_SIZE}
  NUM_CR_RESULTS              = $0000003C;
  {$EXTERNALSYM NUM_CR_RESULTS}

type
//------------------------------------------------------------------------------
// Standardized Return Value data type
//------------------------------------------------------------------------------
  RETURN_TYPE = DWORD;
  {$EXTERNALSYM RETURN_TYPE}
  CONFIGRET = RETURN_TYPE;
  {$EXTERNALSYM CONFIGRET}

//------------------------------------------------------------------------------
// Device Instance Handle data type
//------------------------------------------------------------------------------
  DEVINST = DWORD;
  {$EXTERNALSYM DEVINST}

//------------------------------------------------------------------------------
// Device Instance Identifier data type
// The device instance ID specifies the registry path, relative to the
// Enum key , for a device instance.  For example:  \Root\*PNP0500\0000.
//------------------------------------------------------------------------------
  DEVINSTID_A = PAnsiChar; // Device ID ANSI name.
  {$EXTERNALSYM DEVINSTID_A}
  DEVINSTID = DEVINSTID_A;

implementation
end.

с оригинальным модулем не получалось (Access'ы валились), видно какую-то переменную нужно было инициализировать (типа {DEFINE WINXP}). Пришлось применить грубую силу. smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1461 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.