sprite3
驱动牛犊
驱动牛犊
  • 注册日期2003-10-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3917回复:15

通过Setupapi族函数,如何得到U盘的vid和pid

楼主#
更多 发布于:2005-01-14 11:31
高人指点一二

最新喜欢:

quickerquicke...
sampex
驱动牛犊
驱动牛犊
  • 注册日期2001-03-23
  • 最后登录2010-01-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-01-15 22:57
do you want to get the VID/PID when the device is enumerating OR it is already enumerated?
yyouking
驱动老牛
驱动老牛
  • 注册日期2003-12-18
  • 最后登录2020-04-28
  • 粉丝0
  • 关注0
  • 积分967分
  • 威望114点
  • 贡献值1点
  • 好评度78点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2005-01-16 12:46
这个简单啊
提供: AT89S52+D12开发套件 W78E54+Sl811HST单片机读写U盘套件 PL2303HX-串口转USB 网站http://www.devking.cn 联系 sl811hs@yahoo.com.cn QQ:14441292
dingcai
驱动牛犊
驱动牛犊
  • 注册日期2004-11-08
  • 最后登录2010-04-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-01-16 22:19
在网上搜,有源码。我搜到过的
sprite3
驱动牛犊
驱动牛犊
  • 注册日期2003-10-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-01-17 14:12
各位,详细说说好吗?有源码最好。
我就是想枚举所有的U盘,向获得他们的VID,PID,以及Handle。
我在网上搜过,没有找着合适的。
metalwing
驱动中牛
驱动中牛
  • 注册日期2003-10-13
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分178分
  • 威望58点
  • 贡献值0点
  • 好评度17点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-01-17 14:35
你是说USB设备的VID和PID吗?简单.
用BUSHOUND看枚举过程,在返回的STANDARD DEVICE DESCRIPTOR里包
含了该设备的VID和PID.分别是以0为基数的第8,9字节(VID)和第10,
11字节(PID).
不知我说的对不对.
新手上路,请多关照.
sprite3
驱动牛犊
驱动牛犊
  • 注册日期2003-10-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-01-17 14:53
呵呵,我是要在程序里面读取。
tsingkong
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2013-11-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-01-17 15:33
贴一个自己写的:

// GetDevice.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <WINDOWS.H>
#include <initguid.h>
#include <SetupApi.h> //Project>Setting...>Link>Library>Add "SetupAPI.lib"
#include "DeviceInterfaceClassGUID.h"

int main(int argc, char* argv[])
{
//下面三行输出版本信息,可以不要
printf("GetUSBDevice V3.0(简化版) By 王辉(tsingkong)@CAU 2004-11-08\n");
printf("Press ENTER to continue...\n");
getchar();
//得到InterfaceGUID的设备信息集合
HDEVINFO hDeviceInfo; //设备信息集合的指针
GUID InterfaceGUID; //需要访问的设备的GUID
//DiskClassGuid是硬盘和U盘的GUID,如果是手机,需要修改
//朗科的32M U盘属于FloppyClassGuid
InterfaceGUID=FloppyClassGuid;
//调用SetupDiGetClassDevs得到设备信息集合
hDeviceInfo=SetupDiGetClassDevs(&InterfaceGUID,NULL,NULL,DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);
//如果没有得到说明硬件没有连接好,退出程序
if (hDeviceInfo == INVALID_HANDLE_VALUE)
{ printf("系统中没有这种设备!\n"); return false; }
//得到设备信息集合完毕!
int i=0;
//得到设备信息集合中的第i+1个Interface的信息
while(1)
{
BOOL bRet; //保存函数的返回值
SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData; //保存Interface信息
DeviceInterfaceData.cbSize =sizeof(SP_DEVICE_INTERFACE_DATA);
bRet=SetupDiEnumDeviceInterfaces(hDeviceInfo,NULL,&InterfaceGUID,i++,&DeviceInterfaceData);
//如果bRet等于0,说明没有成功,释放资源,退出程序
if(!bRet) break;
//下面需要得到Interface的详细信息
//先得到详细信息需要的内存大小------------------------------
DWORD RequiredSize;
SetupDiGetDeviceInterfaceDetail(hDeviceInfo,&DeviceInterfaceData,NULL,0,&RequiredSize,NULL);
//然后,就可以为详细信息分配内存了
PSP_INTERFACE_DEVICE_DETAIL_DATA pDeviceDetailData=NULL;
pDeviceDetailData=(PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(RequiredSize);
if(pDeviceDetailData==NULL) break;
//可以得到Interface的详细信息了
DWORD predictLength=RequiredSize;;
pDeviceDetailData->cbSize =sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
bRet=SetupDiGetDeviceInterfaceDetail(hDeviceInfo,&DeviceInterfaceData,pDeviceDetailData,predictLength,&RequiredSize,NULL);
if(!bRet) break;
//pDeviceDetailData->DevicePath保存着设备的路径名
//我们通过它把非USB的设备过滤掉,如果是手机,需要修改
if((strstr(pDeviceDetailData->DevicePath,"USB")==NULL)&&(strstr(pDeviceDetailData->DevicePath,"usb")==NULL))
continue;
//可以打开设备了
char DevicePath[256]; //存储设备的路径名
strcpy(DevicePath,pDeviceDetailData->DevicePath );
strcat(DevicePath,"\\PIPE1");
HANDLE hUSBFile=NULL;
hUSBFile=CreateFile(DevicePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
if(hUSBFile) printf("成功打开设备!\n");
else{ printf("打开设备失败!\n"); break; }
//打开设备成功了,就可以读写了
//可以使用ReadFile,WriteFile,DeviceIoControl
//如果是手机,需要修改
char buffer[1024];
unsigned long RealLength;
//SetFilePointer(hUSBPipe,512*n,FILE_BEGIN);
HANDLE savef=NULL;
savef=CreateFile("C:\\Save.DAT",GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(NULL==savef)
{
printf("Can't Open Save File!");
CloseHandle(hUSBFile);
break;
}
while(ReadFile(hUSBFile,buffer,512,&RealLength,NULL))
{
bRet=WriteFile(savef,buffer,512,&RealLength,NULL);
break;
}
CloseHandle(savef);
// ZeroMemory(buffer,512);
// bRet=SetFilePointer(hUSBFile,0,0,FILE_BEGIN);
// bRet=WriteFile(hUSBFile,buffer,512,&RealLength,NULL);
//最后别忘了关闭设备
if(CloseHandle(hUSBFile)) printf("成功关闭设备!\n");
else printf("关闭设备失败!\n");
}
//退出喽
//释放资源
SetupDiDestroyDeviceInfoList(hDeviceInfo);
//回车退出
printf("Press ENTER to Exit!"); getchar();
return 0;
}
mailto:tsingkong@163.com
tsingkong
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2013-11-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-01-17 15:34
头文件:
DeviceInterfaceClassGUID.h

//keyBoard
DEFINE_GUID(GUID_CLASS_KEYBOARD, 0x884b96c3, 0x56ef, 0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd);
//Mouse
DEFINE_GUID(GUID_CLASS_MOUSE, 0x378de44c, 0x56ef, 0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd );
//Parallel
DEFINE_GUID(GUID_PARALLEL_DEVICE, 0x97F76EF0, 0xF883, 0x11D0, 0xAF, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x5C);
DEFINE_GUID(GUID_PARCLASS_DEVICE, 0x811FC6A5, 0xF728, 0x11D0, 0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1);
//PCMCIA
DEFINE_GUID(GUID_PCMCIA_INTERFACE_STANDARD, 0xbed5dadfL, 0x38fb, 0x11d1, 0x94, 0x62, 0x00, 0xc0, 0x4f, 0xb9, 0x60, 0xee);
//SCSI
DEFINE_GUID(ScsiRawInterfaceGuid, 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(WmiScsiAddressGuid, 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
//Serial
DEFINE_GUID(GUID_CLASS_COMPORT,          0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);
DEFINE_GUID(GUID_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18);
//Storage
DEFINE_GUID(DiskClassGuid,               0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(CdRomClassGuid,              0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(PartitionClassGuid,          0x53f5630aL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(TapeClassGuid,               0x53f5630bL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(WriteOnceDiskClassGuid,      0x53f5630cL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(VolumeClassGuid,             0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(MediumChangerClassGuid,      0x53f56310L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(FloppyClassGuid,             0x53f56311L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(CdChangerClassGuid,          0x53f56312L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
DEFINE_GUID(StoragePortClassGuid,        0x2accfe60L, 0xc130, 0x11d2, 0xb0, 0x82, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
mailto:tsingkong@163.com
sprite3
驱动牛犊
驱动牛犊
  • 注册日期2003-10-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-01-17 16:06
Thanks a lot to tsingkong!
有几个疑问:
第一:if((strstr(pDeviceDetailData->DevicePath,"USB")==NULL)&&(strstr(pDeviceDetailData->DevicePath,"usb")==NULL))
这个判断是否准确?

第二:CreateFile调用为什么要使用strcpy(DevicePath,pDeviceDetailData->DevicePath );
strcat(DevicePath,"\PIPE1");,直接pDeviceDetailData->DevicePath不可以吗?

第三:你的代码没有获得vid和pid吧?
tsingkong
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2013-11-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-01-17 16:21
第一:在现有的情况下可以认为是准确的,再过10年就不知道了:)
第二:我是仿照周立功的书上写的,实际上,直接DevicePath也可以,我记得我试过的。
第三:看下面的这个吧:// GetDevice.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<iostream.h>
#include <WINDOWS.H>
#include <SetupApi.h> //Project>Setting...>Link>Library>Add "SetupAPI.lib"

#define DeviceRegDataSize 256
#define PropertyNum 32

char RegDataDescription[PropertyNum][128];

void PrintGUID(GUID * guid)
{
printf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",guid->Data1 ,\
guid->Data2 ,guid->Data3 ,guid->Data4 [0],guid->Data4 [1],guid->Data4 [2],\
guid->Data4 [3],guid->Data4 [4],guid->Data4 [5],guid->Data4 [6],guid->Data4 [7]);
}

int main(int argc, char* argv[])
{
HDEVINFO hDeviceInfo;
SP_DEVINFO_DATA spDevInfoData;
BOOL bRet;
long loop;
DWORD RequiredSize;
DWORD RegDataType;
BYTE DeviceRegData[DeviceRegDataSize];

printf("GetUSBDevice V1.0 By 王辉(tsingkong)@CAU 2004-11-04\n");
printf("Press ENTER to continue...\n");
getchar();
for(loop=0;loop<PropertyNum;loop++)
strcpy(RegDataDescription[loop],"unused");
strncpy(RegDataDescription[SPDRP_DEVICEDESC],"DeviceDesc (R/W)",127);
strncpy(RegDataDescription[SPDRP_HARDWAREID],"HardwareID (R/W)",127);
strncpy(RegDataDescription[SPDRP_COMPATIBLEIDS],"CompatibleIDs (R/W)",127);
strncpy(RegDataDescription[SPDRP_UNUSED0],"unused",127);
strncpy(RegDataDescription[SPDRP_SERVICE],"Service (R/W)",127);
strncpy(RegDataDescription[SPDRP_UNUSED1],"unused",127);
strncpy(RegDataDescription[SPDRP_UNUSED2],"unused",127);
strncpy(RegDataDescription[SPDRP_CLASS],"Class (R--tied to ClassGUID)",127);
strncpy(RegDataDescription[SPDRP_CLASSGUID],"ClassGUID (R/W)",127);
strncpy(RegDataDescription[SPDRP_DRIVER],"Driver (R/W)",127);
strncpy(RegDataDescription[SPDRP_CONFIGFLAGS],"ConfigFlags (R/W)",127);
strncpy(RegDataDescription[SPDRP_MFG],"Mfg (R/W)",127);
strncpy(RegDataDescription[SPDRP_FRIENDLYNAME],"FriendlyName (R/W)",127);
strncpy(RegDataDescription[SPDRP_LOCATION_INFORMATION],"LocationInformation (R/W)",127);
strncpy(RegDataDescription[SPDRP_PHYSICAL_DEVICE_OBJECT_NAME],"PhysicalDeviceObjectName (R)",127);
strncpy(RegDataDescription[SPDRP_CAPABILITIES],"Capabilities (R)",127);
strncpy(RegDataDescription[SPDRP_UI_NUMBER],"UiNumber (R)",127);
strncpy(RegDataDescription[SPDRP_UPPERFILTERS],"UpperFilters (R/W)",127);
strncpy(RegDataDescription[SPDRP_LOWERFILTERS],"LowerFilters (R/W)",127);
strncpy(RegDataDescription[SPDRP_BUSTYPEGUID],"BusTypeGUID (R)",127);
strncpy(RegDataDescription[SPDRP_LEGACYBUSTYPE],"LegacyBusType (R)",127);
strncpy(RegDataDescription[SPDRP_BUSNUMBER],"BusNumber (R)",127);
strncpy(RegDataDescription[SPDRP_ENUMERATOR_NAME],"Enumerator Name (R)",127);
strncpy(RegDataDescription[SPDRP_SECURITY],"Security (R/W, binary form)",127);
strncpy(RegDataDescription[SPDRP_SECURITY_SDS],"Security (W, SDS form)",127);
strncpy(RegDataDescription[SPDRP_DEVTYPE],"Device Type (R/W)",127);
strncpy(RegDataDescription[SPDRP_EXCLUSIVE],"Device is exclusive-access (R/W)",127);
strncpy(RegDataDescription[SPDRP_CHARACTERISTICS],"Device Characteristics (R/W)",127);
strncpy(RegDataDescription[SPDRP_ADDRESS],"Device Address (R)",127);
strncpy(RegDataDescription[SPDRP_UI_NUMBER_DESC_FORMAT],"UiNumberDescFormat (R/W)",127);
strncpy(RegDataDescription[SPDRP_MAXIMUM_PROPERTY],"Upper bound on ordinals",127);

hDeviceInfo=SetupDiGetClassDevs(NULL,"USB",NULL,DIGCF_ALLCLASSES|DIGCF_PRESENT);
if (hDeviceInfo == INVALID_HANDLE_VALUE)
{ printf("访问系统硬件出错!"); return false; }
spDevInfoData.cbSize =sizeof(SP_DEVINFO_DATA);
for(loop=0;SetupDiEnumDeviceInfo(hDeviceInfo,loop,&spDevInfoData);loop++)
{
printf("第%d个USB设备:\n",loop+1);
for(int i=0;i<PropertyNum;i++)
{
if(strcmpi("unused",RegDataDescription)==0) continue;
memset(DeviceRegData,0,DeviceRegDataSize);
RequiredSize=0;
SetupDiGetDeviceRegistryProperty(hDeviceInfo,&spDevInfoData,\
i,&RegDataType,(PBYTE)DeviceRegData,DeviceRegDataSize,&RequiredSize);

if(RequiredSize<=0) continue;
printf("\t%s:",RegDataDescription);
if((RegDataType==REG_SZ)||(RegDataType==REG_MULTI_SZ)||(RegDataType==REG_EXPAND_SZ))
printf("%s",DeviceRegData);
else if(RegDataType==REG_DWORD)
{
printf("0x%X(%d)",((DWORD *)DeviceRegData)[0],((DWORD *)DeviceRegData)[0]);
}
else if(strstr(RegDataDescription,"BusTypeGUID"))
{
PrintGUID((GUID*)DeviceRegData);
}
else{
for(unsigned int j=0;j<RequiredSize;j++)
printf("%02X",((PBYTE)DeviceRegData)[j]);
}
printf("\n");
}
}
printf("Total:%d\n",loop);
bRet=SetupDiDestroyDeviceInfoList(hDeviceInfo);
printf("Press ENTER to Exit!");
getchar();
return 0;
}

mailto:tsingkong@163.com
tsingkong
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2013-11-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-01-17 16:25
貌似通过SetupDiGetDeviceRegistryProperty得到设备信息的。
PID和VID都在注册表里面呢。
时间长了,很多东西都忘了。
不妥之处请莫见怪。
mailto:tsingkong@163.com
sprite3
驱动牛犊
驱动牛犊
  • 注册日期2003-10-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-01-17 21:35
严重感谢!

已经放了一半的分了(50哦)。

再请教一下,第一个程序里面获得的读写handle怎么和第二个程序里面获得的vid、pid对应上?也就是说,在可能有多个U盘的情况下,如何确保获得的handle和vid都指向同一个U盘。

结构SP_DEVINFO_DATA里面的 DevInst 是啥意思?和handle类似的意思?
tsingkong
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2013-11-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-01-17 22:16
关于SP_DEVINFO_DATA,你那里没有MSDN吗:)
关于如何对上的问题,我也有疑问。
我上面贴的两段程序,根据U盘的两种属性分别对其访问。
如果同时插上两个牌子的U盘肯定可以分别将Handle和vid,pid对应上。
如果是同一个牌子的,那就不行了,handle肯定不同,但是vid,pid极有可能相同。
mailto:tsingkong@163.com
liweiqiao
驱动牛犊
驱动牛犊
  • 注册日期2004-10-08
  • 最后登录2007-09-27
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-01-18 08:23
其实,我也写过这样的程序.如果是同一牌子的两个U盘,它们的VID是相同的,同一系列的产品PID也相同,不同系列的产品PID就不同了.如果要区分的话,可以依据它们的Serial Number(序列号)来区分,这个东西是唯一标识一个设备的.
sprite3
驱动牛犊
驱动牛犊
  • 注册日期2003-10-10
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2005-01-18 09:07
关于SP_DEVINFO_DATA,你那里没有MSDN吗:)
关于如何对上的问题,我也有疑问。
我上面贴的两段程序,根据U盘的两种属性分别对其访问。
如果同时插上两个牌子的U盘肯定可以分别将Handle和vid,pid对应上。
如果是同一个牌子的,那就不行了,handle肯定不同,但是vid,pid极有可能相同。


呵呵,关于如何对应上的问题我琢磨很久了。不知道具体怎么做,在这里也搜了很久了。
游客

返回顶部