-
В чем собственно проблема. Не получается получить путь устройства. Делаю так:
LoadSetupApi;
LoadConfigManagerApi;
Memo1.Clear;
PnPHandle:=SetupDiGetClassDevs(@USB_CLASS_GUID, nil, 0,DIGCF_PRESENT);
if Cardinal(PnPHandle) = INVALID_HANDLE_VALUE then Exit;
Devn := 0;
repeat
DevData.cbSize := SizeOf(DevData);
RES := SetupDiEnumDeviceInfo(PnPHandle, Devn, DevData);
if (RES) and (_DN<>DN_ROOT_ENUMERATED) then
begin
St:=GetDeviceName(PnPHandle, DevData);
if St='AVR309:USB to UART protocol converter' then begin
DeviceInterfaceDetailData:=nil;
RequiredSize:=nil;
new(RequiredSize);
if(SetupDiGetInterfaceDeviceDetail(PnPHandle,
@DevData,
nil,
0,
RequiredSize,
nil))then begin
new(DeviceInterfaceDetailData);
DeviceInterfaceDetailData^.cbSize:=SizeOf(DeviceInterfaceDetailData^);
SetupDiGetInterfaceDeviceDetail(PnPHandle,
@DevData,
DeviceInterfaceDetailData,
RequiredSize^,
nil,
nil);
Memo1.Lines.Add('OK');
Memo1.Lines.Add(IntToStr(Length(DeviceInterfaceDetailData^.DevicePath)));
end;
end;
Inc(Devn);
end;
until not RES;
SetupDiDestroyDeviceInfoList(PnPHandle);
UnloadSetupApi;
UnloadConfigManagerApi;
Предполагаю, что неправильно использую функцию SetupDiGetInterfaceDeviceDetail. Может кто то работал с данной функцией? dimonbest на форуме Добавить отзыв для dimonbest Пожаловаться на это сообщение Ответить с цитированием
-
Вот пример, у меня работает. GIUD поменяешь.
procedure GetDeviceInfo;
var
h_DevInfo: HDEVINFO;
DeviceNumber: DWORD;
DevData: TSPDevInfoData;
DevInfoData: TSPDeviceInterfaceData;
DevInfoDetail: PSPDeviceInterfaceDetailData;
RES:BOOL;
requiredLength: PDWORD;
predictedLength: DWORD;
begin
h_DevInfo := SetupDiGetClassDevs(@GUID_CLASS_USB_DEVICE, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
if h_DevInfo = INVALID_HANDLE_VALUE then Exit;
DeviceNumber := 0;
repeat
DevData.cbSize := SizeOf(TSPDevInfoData);
DevInfoData.cbSize := SizeOf(TSPDeviceInterfaceData);
RES := SetupDiEnumDeviceInterfaces(h_DevInfo, nil, GUID_CLASS_USB_DEVICE, DeviceNumber, DevInfoData);
if (RES) then
begin
SetupDiGetInterfaceDeviceDetail(h_DevInfo,
@DevInfoData,
nil,
0,
requiredlength,
nil);
predictedLength := requiredLength^;
GetMem(DevInfoDetail, predictedLength);
DevInfoDetail^.cbSize := Sizeof(TSPDeviceInterfaceDetailData);
if SetupDiGetInterfaceDeviceDetail(h_DevInfo,
@DevInfoData,
DevInfoDetail,
predictedLength,
requiredLength,
@DevData)
then
begin
DevPath:=PChar(@DevInfoDetail.devicepath);
Memo1.Lines.Add(DevPath);
end;
FreeMem(DevInfoDetail);
Inc(DeviceNumber);
end;
until not RES;
SetupDiDestroyDeviceInfoList(h_DevInfo);
end;
-
Не знаю что у тебя в LoadSetupApi, но на всякий случай...
type
HDEVINFO = THandle;
PSPDevInfoData = ^TSPDevInfoData; SP_DEVINFO_DATA = packed record cbSize: DWORD; ClassGuid: TGUID; DevInst: DWORD; // DEVINST handle Reserved: ULONG_PTR; end; TSPDevInfoData = SP_DEVINFO_DATA;
PSPDeviceInterfaceData = ^TSPDeviceInterfaceData; SP_DEVICE_INTERFACE_DATA = packed record cbSize: DWORD; InterfaceClassGuid: TGUID; Flags: DWORD; Reserved: ULONG_PTR; end; TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;
PSPDeviceInterfaceDetailData = ^TSPDeviceInterfaceDetailData; SP_DEVICE_INTERFACE_DETAIL_DATA = packed record cbSize: DWORD; DevicePath: array [0..0] of Char; end; TSPDeviceInterfaceDetailData = SP_DEVICE_INTERFACE_DETAIL_DATA;
-
Спасибо за ответ, уже как месяц борюсь с этой проблемой! У меня проект не компилит, выдает ошибки, например
[Error] Unit1.pas(31): Undeclared identifier: 'ULONG_PTR'
Какие модули надо добавлять в uses?
-
А если делаю через LoadConfigManagerApi unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SetupAPI, Cfg, CfgMgr32;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
public
end;
var
Form1: TForm1;
implementation
procedure GetDeviceInfo;
const
USB_CLASS_GUID:TGUID = '';
USB_DEVICE_GUID:TGUID = '';
var
h_DevInfo: HDEVINFO;
DeviceNumber: DWORD;
DevData: TSPDevInfoData;
DevInfoData: TSPDeviceInterfaceData;
DevInfoDetail: PSPDeviceInterfaceDetailData;
RES:BOOL;
requiredLength: PDWORD;
predictedLength: DWORD;
devpath: string;
begin
form1.Memo1.Clear;
h_DevInfo := SetupDiGetClassDevs(@USB_CLASS_GUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
if cardinal(h_DevInfo) = INVALID_HANDLE_VALUE then Exit;
DeviceNumber := 0;
repeat
DevData.cbSize := SizeOf(TSPDevInfoData);
DevInfoData.cbSize := SizeOf(TSPDeviceInterfaceData);
RES := SetupDiEnumDeviceInterfaces(h_DevInfo, nil, USB_CLASS_GUID, DeviceNumber, DevInfoData);
if (RES) then
begin
SetupDiGetInterfaceDeviceDetail(h_DevInfo,
@DevInfoData,
nil,
0,
requiredlength,
nil);
predictedLength := requiredLength^;
GetMem(DevInfoDetail, predictedLength);
DevInfoDetail^.cbSize := Sizeof(TSPDeviceInterfaceDetailData);
if SetupDiGetInterfaceDeviceDetail(h_DevInfo,
@DevInfoData,
DevInfoDetail,
predictedLength,
requiredLength,
@DevData)
then
begin
DevPath:=PChar(@DevInfoDetail.devicepath);
form1.Memo1.Lines.Add('ok');
form1.Memo1.Lines.Add(DevPath);
end;
FreeMem(DevInfoDetail);
Inc(DeviceNumber);
end;
until not RES;
SetupDiDestroyDeviceInfoList(h_DevInfo);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetDeviceInfo;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
LoadConfigManagerApi;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
UnloadConfigManagerApi;
end;
end. То когда передаю USB_CLASS_GUID:TGUID = '{36FC9E60-C465-11CF-8056-444553540000}'; RES := SetupDiEnumDeviceInterfaces(h_DevInfo, nil, USB_CLASS_GUID, DeviceNumber, DevInfoData); Равно False А если передаю USB_DEVICE_GUID:TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}'; То в этом месте: DevInfoDetail^.cbSize := Sizeof(TSPDeviceInterfaceDetailData); Происходит исключение - Access violation at address 0045A92F in module 'Project1.exe'. Read of address 00000003. В чем может быть проблема?
-
У меня как-то так примерно...
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
const
GUID_CLASS_USB_DEVICE:TGUID='';
type
ULONG_PTR = ^ ULONG;
HDEVINFO = THandle;
PSPDevInfoData = ^TSPDevInfoData;
SP_DEVINFO_DATA = packed record
cbSize: DWORD;
ClassGuid: TGUID;
DevInst: DWORD; Reserved: ULONG_PTR;
end;
TSPDevInfoData = SP_DEVINFO_DATA;
PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;
SP_DEVICE_INTERFACE_DATA = packed record
cbSize: DWORD;
InterfaceClassGuid: TGUID;
Flags: DWORD;
Reserved: ULONG_PTR;
end;
TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;
PSPDeviceInterfaceDetailData = ^TSPDeviceInterfaceDetailData;
SP_DEVICE_INTERFACE_DETAIL_DATA = packed record
cbSize: DWORD;
DevicePath: array [0..0] of Char;
end;
TSPDeviceInterfaceDetailData = SP_DEVICE_INTERFACE_DETAIL_DATA;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
private
public
end;
var
Form1: TForm1;
implementation
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): BOOL; stdcall; external 'SetupApi.dll';
function SetupDiEnumDeviceInterfaces(DeviceInfoSet: HDEVINFO;
DeviceInfoData: PSPDevInfoData;
const InterfaceClassGuid: TGUID;
MemberIndex: DWORD;
var DeviceInterfaceData: TSPDeviceInterfaceData): BOOL; stdcall; external 'SetupApi.dll';
function SetupDiGetInterfaceDeviceDetail(DeviceInfoSet: HDEVINFO;
DeviceInterfaceData: PSPDeviceInterfaceData;
DeviceInterfaceDetailData: PSPDeviceInterfaceDetailData;
DeviceInterfaceDetailDataSize: DWORD;
RequiredSize: PDWORD;
Device: PSPDevInfoData): BOOL; stdcall; external 'SetupApi.dll' name 'SetupDiGetDeviceInterfaceDetailA';
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall; external 'SetupApi.dll';
процедуры
end.
-
Огромное человеческое спасибо. Код использовал свой, но Ваш помог разобраться что не так. я неправильно получал путь. Получал так: result:=DeviceInterfaceDetailData.DevicePath; Оно выдовало симол "/" А надо так: result:=pchar(@DeviceInterfaceDetailData.DevicePath); И выдает то что надо! :-)
-
Please, I'm Brazilian USB Developer and I can't read your description, but I understand your code. I stopped at the same point: DevInfoDetail^.cbSize := Sizeof(TSPDeviceInterfaceDetailData); and I found the same error (Access Violation at address...)
Can you to solve this error?
Thank you so much!
-
-
Thank You, Rouse.
Best Regards!!!
-
SetupDiEnumDeviceInterfaces выдает ошибку 259 не знаете почему?
-
Здравствуйте у меня возникла такая проблема в коде который выше приведены SetupDiEnumDeviceInterfaces выдает ошибку 259 не знаете почему?
-
В чьём коде конкретно ? И настоятельно рекомендую сделать
var LastError: Integer;
...
SetLastError(0);
...
LastError := GetLastError;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nil, LastError, LANG_SYSTEM_DEFAULT, chBufErr, 80, nil);
MessageDlg('Error №'+IntToStr(LastError)+' :'+chBufErr, mtError, [mbOK], 0);
И узнаете на что SetupDiEnumDeviceInterfaces ругаеццо...
-
Все эта проблема была из за не правильного GUID-a Я до этого использовал вот эти USB_CLASS_GUID:TGUID = '{36FC9E60-C465-11CF-8056-444553540000}'; USB_DEVICE_GUID:TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
но правильный вот такая GUID_DEVINTERFACE_DISK: TGUID = ( D1:$53f56307; D2:$b6bf; D3:$11d0; D4:($94, $f2, $00, $a0, $c9, $1e, $fb, $8b));
-
Люди, доброго времени суток. Мне бы проникнуть к памяти телефона, для восстановления инф. и необходимо прописать путь в прог-у, не подскажите как этот путь найти и вообще возможно ли это?
-
Хм... А вы уверены, что всё так просто ? Систему команд и сервисную документацию телефона изучили ? Если ДА на оба вопроса - то дело за малым, открыть порт зная vid & pid & GUID не так уж сложно. См. пример выше. В сети много таких примеров, в том числе с поиском всех USB-устройств на шине и отслеживании WM_DEVICEARRIVAL в реальном времени.
-
Начнем с того, что я "агроном любитель"... Нужно просто очень очень восстановить запись на тел. Если бы он определялся как носитель - это было бы все гораздо проще... Док-ию изучил, восстановления данных там нет, как хотелось бы(что тоже очень упростило бы ситуацию). Сейчас остался вариант восстановить инф-ю через прог. (напр. Recova) ну или др. не важно. Но они работают с определенным разделом или диском, а который нужно указывать путь... а так как тел. не опр. как носитель, его путь мне неизвестен и открывается он только через PC Studio. Я конечно пробовал указывать путь, как написано в диспетчере устр. Пример: usb\root_hub Что то вроде того, все перепробовал, щас просто тел. нет под рукой, он гулять ушел)) Я не утверждаю что я делаю все правильно просто экспериментирую... так что сильно не смейтесь) ... вот прога эта не понимает путь!!! Возможно ей его как-нибуть прописать, чтоб достучаться до внутр.памяти тел.????
-
А гуглить на тему ближайшего АСЦ (Авторизованного Сервисного Центра) по производителю телефона не пробовали ? Как правило производитель телефонов высылает АСЦ специализированный софт. В вашей ситуации - это самый простой на текущий момент выход. Не спорю, есть люди, которые не один год посвятили работой с телефонами на программном уровне, помнится еще лет 7-8 назад первые "альтернативные производителю" программы появились. Но таких людей мало и они как правило обладают специализированной документацией для написания программ. А Рекува работает только с ЛОГИЧЕСКИМИ дисками (не путать с физическим наличием носителя на шине) или ТОМАМИ. Если диск в системе не определяется - она не поможет.
-
Да, на всякий случай, GUID_DEVINTERFACE_VOLUME: TGuid = {53F5630D-B6BF-11D0-94F2-00A0C91EFB8B};
-
Спасибо! АСЦ - для незаморачивающихся людей)))
-
Ребят, поясните плиз. Вот я получил в посте Дмитрия от (31.07.09 08:01) [1]
...
DevPath:=PChar(@DevInfoDetail.devicepath);
Это то имя устройства, которое я могу использовать в CreateFile? Вопрос задаю потому, что у меня USB термопринтер китайский (GPrinter GP3120-T), не поддерживает русские шрифты и мне надо сформировать картинку с текстом и отправить на него как команды принтера напрямую. Через COM3 все ок, но медленно. Его родная программа умеет с ним работать через COM и через USB (у принтера два порта). Понятно, что через USB быстрее на много. Но GDI драйвера в системе на этот принтер нет т.е. я не могу использовать обычный спулер печати. Я нашел имя этого устройства (пусть пока вручную с помощью программы от Rouse_. Имя такое: \Device\USBPDO-5. Вот тут http://www.itshop.ru/Visual-C-Rabota-s-USB-ustroystvami/l9i22755 (см. в самом конце статьи листинг) они передают именно devinfodetail->devicepath. Если я передаю это имя, то получаю "Системе не удается найти указанный путь", как будто я открываю файл на диске. Аналогично я пробовал подставить имя порта COM1, он у меня есть в системе и его devinfodetail->devicepath = ' \Device\0000006f', получаю ту же ошибку. А вот если вызову как 'COM1', то все нормально. Пробовал впереди писать '\\.', но толку нет. Может кто подскажет где собака порылась?
-
> Может кто подскажет где собака порылась?
CreateFile не откроет такие пути, используй ZwOpenFile()
|