WINCE下USB驱动程序_第1页
WINCE下USB驱动程序_第2页
WINCE下USB驱动程序_第3页
WINCE下USB驱动程序_第4页
WINCE下USB驱动程序_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、如何编写 WINDOWS CE.NET USB驱动程序发表:不详 阅读:| $ |226次 关键字:字体:大 中小随着USB设备的普及,摆在开发人员面前的驱动开发任务也是越来越繁重了,特别是对于一些嵌入式开发厂商来讲,由于设备所采用的操作系统不同,相应的硬件接口也是不一样的, 开发相关的USB驱动程序更是难上加难。Windows CE.NET是微软推出的功能强大的嵌入式 操作系统,国内采用此操作系统的厂商已经很多了,本文就以wi ndows 为例,简单介绍一下如何开发 windows 下的USB驱动程序。首先要熟悉一些 USB的基本概念,当然最好把USB 1.1的协议看一遍,(当然现在2。0的

2、协议都已经有了)上可以下载,我记得好像有个中文版的,翻译的还可以,上有的,具体位置记不太清楚了,中文版的协议可以快速翻一边,了解一些基本的概念, 但是设计到一些关键性的东西最好还是看英文版的心 里比较清楚些。这里我就不介绍 USB的基本协议了,假设用户已经熟悉了 USB设备的一些基本的概念,并且对 Winows CE.NET的开发有一定的了解。下面简略介绍一下 Windows CE.NET中USB设备驱动开发的一些基础知识。Windows CE.NET的USB系统软件分为两层:USB Client设备驱动程序和底层的 Windows CE实现的函数层。USB设

3、备驱动程序主要负责利用系统提供的底层接口配置设备,和设备进行通讯。底层的函数提本身又由两部分组成,通用串行总线驱动程序(USBD模块和较低的主控制器驱动程序(HCD模块。HCD负责最最底层的处理,USBD莫块实现较高的 USBD函数接 口。USB设备驱动主要利用 USBC接口函数和他们的外围设备打交道。USB设备驱动程序主要和 USBD丁交道,所以我们必须详细的了解USBD提供的函数。主要的传输函数有:AbourtTra nsferIssueC on trolTra nsferCloseTra nsferGetIsochResultGetTra nsferStatusIssueBulkTra

4、nsferIssue In terrupTra nsfer IssueIsochTra nsferIstra nsferComplete IssueVe ndorTra nsfer主要的用于打开和关闭AbortPipeTra nsfers IsDefaultPipeHalted Open PipeResetPipeUSBD和 USB设备之间的通信通道的函数有:ClosePipeIsPipeHaltedResetDefaultPipe相应的打包函数接口有:GetFrameLe ngthGetFrameNumberReleaseFrameLe ngthC ontrolSetFrameLe ngth

5、TakeFrameLe ngthC on trol取得设置设备配置函数:ClearFeature GetDescriptor GetI nteface GetStatusSetDescriptor SetFeature SetI nteface Syn cFrame与USB进行交互的实现方法相关的多任务函数:Findln terfaceGetDeviceI nfoGetUSBDVersio nLoadGe nericl ntefaceDriverOpe nClie ntRegisterKeyRegisterClie ntDeviceldRegisterClie ntSett ings Regi

6、sterNotificatio nRouti ne Tran slateStri ngDescrUn RegisterNotificatio nRouti ne常见的Windows CE.NET下USB的设备驱动程序的编写有以下几种方法流式接口函数这种驱动程序主要呈现流式函数接口,主要输出XXX_I nit,XXX_Dei nit,XXX_Ope n, XXX_Close,XXX_Ope n,XXX_Close,XXX_Read,XXX_Write, XXX_Seek,XXX_IOCo ntrol,XXX_PowerUp,XXX_PowerDow n 等流式接口,注意上述的几个接口 一定都要输

7、出,另外XXX必须为三个字符,否则会出错。但是此类的驱动程序不是通过设备 管理接口来加载的,所以必须手工的调用RegisterDevice ()和DeregisterDevice ()函数来加载和卸载驱动程序。用户可以将此类的设备作为标准的文件来操作,只要调用相应的文件操作就可以和驱动程序打交道。使用现有的Window CE.NET的应用程序接口此类设备主要是利用 Win dows CE.NET中已经有了现成的函数接口,例如 USB Mass Storage Disk,它主要利用现有的 Windows CE.Net中已经有的可安装文件系统接口,呈现给系统可 用的文件系统,对于用户来讲,它是透明

8、的,用户仅仅感觉在操作一个文件夹。创建指定到特定的 USBD的用户指定的API这种方法在USB*现设备时不需要任何限制,主要是特制的提供API给用户,一般不太常见。USB设备驱动程序必须输出的函数有: USBDeviecAttach当USB设备连接到计算机上时,USBD莫块就会调用此函数,这个函数主要用于初始化USB设备,取得USB设备信息,配置 USB设备,并且申请必需的资源。 USBI nstallDriver主要用于创建一个驱动程序加载所需的注册表信息,例如读写超时,设备名称等。 USBU nin stallDriver主要用于释放驱动程序所占用的资源,以及删除USBI nstallDr

9、iver函数创建的注册表等。上述的三个函数接口是所有的USB驱动程序必须提供的,缺一不可。另外比较重要的是 USB设备驱动程序的注册表配置,一般的USB设备驱动程序的注册表配置在 HKEY_LOCAL_MACHINEDriversUSBLoadClients 下,每个驱动程序的子键都有GrouplDGroup2_IDGroup3_IDDriverName 格式,如果注册表信息与 USB设备信息符合,USBD就会加载此驱动程序。否则设备的子键应该由供应商,设备类和协议信息通过下划线 组成。具体的配置举个例子:例如你有个PDA设备,它具有一个 USB接口,它的供应厂商ID假设为0x0888,设备I

10、D为 0x0999,没有使用特殊的协议,那么它的加载注册表应该写为:HKEY_LOCAL_MACHINEDriversUSBLoadClie nts2184_2457DefaultDefaultPDA "DLL"="pdausb.dll"需要注意的是注册表构成都是十进制数值来标识的,注意一下十进制和十六进制的转换。再举个USB鼠标的例子,USB鼠标是标准的 HID设备,它的协议为:InterfaceClassCode 为 3( HID 类),InterfaceSubclassCode 为 1 (引导接口类),InterfaceProtocolCode 为

11、 2 (鼠标协议类),所以它的注册如下:HKEY_LOCAL_MACHINEDriversUSBLoadClie ntsDefaultDefault3_1_2USBMouse "DLL"="usbmouse.dll"到此为止,我们可以看出,其实驱动开发无非做两件事情,一件是和硬件打交道,另外一件是和操作系统打交道。举个简单的例子,例如:我们需要开发一个 USB鼠标驱动程序,我们就需要了解USB鼠标硬件上是怎么发送数据的?操作系统怎么才能得到鼠标的控制事件?其实USB鼠标是有一个中断 PIPE的,用于传送鼠标产生的数据,Windwos CE.NET中有个接

12、口函数叫做mouse_event(),专门用于产生鼠标事件,但是它是不关心具体什么硬件的,甚 至我们自己在应用程序中调用这个函数都可以实现模拟鼠标,对应的有个keybd_event (),用于产生键盘事件,知道了这个就好办多了,只要将相应的数据转换一下,调用一下mouse_event () 即可,上述讲了堆理论,可能读者脑袋都已经大了,为此,我们举个简单的例子来详细说明一下驱动程序的开发过程。例如我们有个USB Mouse设备,设备信息描述如下:Device Descriptor:bcdUSB: 0x0100bDeviceClass: 0x00bDeviceSubClass: 0x00bDev

13、iceProtocol: 0x00bMaxPacketSize0: 0x08 (8)idVen dor: 0x05E3 (Ge nesys Logic Inc.)idProduct: 0x0001bcdDevice: 0x0101iManu facturer: 0x00iProduct: 0x01iSerialNumber: 0x00bNumConfigurations: 0x01Connection Status: DeviceC onn ectedCurrent Config Value: 0x01Device Bus Speed: LowDevice Address: 0x02Open

14、Pipes: 1En dpo int Descriptor:bEn dpoi ntAddress: 0x81Tran sfer Type: In terruptwMaxPacketSize: 0x0003 (3)bln terval: 0x0A可以看出上述设备有一个中断PIPE,包的最大值为3。可能有人问上述的值怎么得到的,win2k的DDK中有个usbview的例程,编译一下,将你的USB设备插到PC机的USB口中,运行usbview.exe即可看得相应的设备信息。有了这些基本信息,就可以编写 USB设备了,首先声明一下,下面的代码取自微软的USB鼠标样本程序,版权归微软所有,此处仅仅借用来

15、描述一下 USB鼠标驱动的开发过程, 读者 如需要引用此代码,需要得到微软的同意。首先,必须输出 USBD要求调用的三个函数,首先到设备插入到USB端 口时,USBD会调用USBDeviceAttach()函数,相应的代码如下:extern "C" BOOLUSBDeviceAttach(USB_HANDLE hDevice, / USB 设备句柄LPCUSB_FUNCS lpUsbFuncs, / USBDI 的函数集合LPCUSB_INTERFACE lp In terface, /设备接口描述信息LPCWSTR szUniqueDriverld,/ 设备 ID 描述字

16、符串。LPBOOL fAcceptControl,/返回TRUE标识我们可以控制此设备,反之表示不能控制DWORD dwUn used)*fAcceptC on trol = FALSE;/我们的鼠标设备有特定的描述信息,要检测是否是我们的设备。if (l pl nterface = NULL)return FALSE;/打印相关的USB设备接口描述信息。DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: DeviceAttach, IF %u, #EP:%u, Class:%u, Sub:%u,Prot:%urn"),Ipl nteface->D

17、escriptor.bl ntefaceNumber,lpl nteface->Descriptor.bNumE ndpoi nts,Ipln terface->Descriptor.b In terfaceCIass,Ip In terface->Descriptor.b In terfaceSubCI ass,lp In terface->Descriptor.b In tefaceProtocol);II初试数据USB鼠标类,产生一个接受USB鼠标数据的线程CMouse * pMouse = new CMouse(hDevice, IpUsbF un cs, Ip

18、 In terface);if (pMouse = NULL)return FALSE;if (! pMouse->I ni tialize()delete pMouse;return FALSE;II注册一个监控USB设备事件的回调函数,用于监控USB设备是否已经拔掉。(*IpUsbF un cs->IpRegisterNotificati on Routi ne)(hDevice,USBDeviceNotificatio ns, pMouse);*fAcceptC on trol = TRUE;return TRUE;第二个函数是 USBI nstallDriver ()函数,

19、一些基本定义如下:const WCHAR gcszRegisterClie ntDriverld = L"RegisterCIie ntDriverID"const WCHAR gcszRegisterClie ntSetti ngs = L"RegisterCIie ntSetti ngs"con st WCHAR gcsz Un RegisterClie ntDriverld = L"U nRegisterClie ntDriverID"con st WCHAR gcsz Un RegisterClie ntSetti ngs =

20、 L"U nRegisterClie ntSetti ngs"con st WCHAR gcszMouseDriverId = L"Ge neric_Sample_Mouse_Driver"函数接口如下:extern "C" BOOLUSBI nstallDriver(LPCWSTR szDriverLibFile) II parm IN - Con tai ns clie nt driver DLL nameBOOL fRet = FALSE;HINSTANCE hl nst = LoadLibrary(L"USBD.DL

21、L");II注册USB设备信息if(hl nst)LPREGISTER_CLIENT_DRIVER_ID pRegisterld = (LPREGISTER_CLIENT_DRIVER_ID) GetProcAddress(hInst, gcszRegisterClientDriverld);LPREGISTER_CLIENT_SETTINGS pRegisterSetti ngs = (LPREGISTER_CLIENT_SETTINGS) GetProcAddress(hl nst, gcszRegisterClie ntSett in gs);if(pRegisterld &a

22、mp;& pRegisterSettings)USB_DRIVER_SETTINGS DriverSetti ngs;DriverSett in gs.dwCo unt = sizeof(DriverSett in gs);/设置我们的特定的信息。DriverSetti ngs.dwVe ndorld = USB_NO_INFO;DriverSetti ngs.dwProductld = USB_NO_INFO;DriverSetti ngs.dwReleaseNumber = USB_NO_INFO;DriverSetti ngs.dwDeviceClass = USB_NO_INF

23、O;DriverSetti ngs.dwDeviceSubClass = USB_NO_INFO;DriverSetti ngs.dwDeviceProtocol = USB_NO_INFO;DriverSetti ngs.dwl nterfaceClass = 0x03; / HIDDriverSett in gs.dwl nterfaceSubClass = 0x01; / boot deviceDriverSett in gs.dw In terfaceProtocol = 0x02; / mousefRet = (*pRegisterld)(gcszMouseDriverld);if(

24、fRet)fRet = (*pRegisterSetti ngs)(szDriverLibFile, gcszMouseDriverld, NULL, & DriverSetti ngs);if(!fRet)/BUGBUG un register the Clie nt Drivers IDelseRETAILMSG(1,(TEXT(”!USBMouse: Error gett ing USBD fun ctio n poi ntersrn"); FreeLibrary(hI nst);return fRet;USB设备驱动上述代码主要用于产生USB设备驱动程序需要的注册表信

25、息,需要注意的是:程序不使用标准的注册表函数,而是使用RegisterClie ntDriverlD ()和RegisterClie ntSett in gs来注册相应的设备信息。另外一个函数是 USBU nin stallDriver()函数,具体代码如下:extern "C" BOOLUSBU nln stallDriver()BOOL fRet = FALSE;HINSTANCE hI nst = LoadLibrary(L"USBD.DLL");if(hI nst)LPUN_REGISTER_CLIENT_DRIVER_ID pUn Regist

26、erId = (LPUN_REGISTER_CLIENT_DRIVER_ID)GetProcAddress(hl nst, gcsz Un RegisterClie ntDriverld);LPUN_REGISTER_CLIENT_SETTINGS pUn RegisterSetti ngs = (LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress(h In st, gcsz Un RegisterClie ntSett in gs);if(pUn RegisterSett in gs)USB_DRIVER_SETTINGS DriverSetti ng

27、s;DriverSett in gs.dwCo unt = sizeof(DriverSett in gs);/必须填入与注册时相同的信息。DriverSetti ngs.dwVe ndorld = USB_NO_INFO;DriverSetti ngs.dwProductld = USB_NO_INFO;DriverSetti ngs.dwReleaseNumber = USB_NO_INFO;DriverSetti ngs.dwDeviceClass = USB_NO_INFO;DriverSetti ngs.dwDeviceSubClass = USB_NO_INFO;DriverSet

28、ti ngs.dwDeviceProtocol = USB_NO_INFO;DriverSetti ngs.dwl nterfaceClass = 0x03; / HIDDriverSett in gs.dwl nterfaceSubClass = 0x01; / boot deviceDriverSett in gs.dw In terfaceProtocol = 0x02; / mousefRet = (*p Un RegisterSett in gs)(gcszMouseDriverId, NULL,&DriverSett in gs);if(pUn Registerld)BOO

29、L fRetTemp = (*p Un Registerld)(gcszMouseDriverld);fRet = fRet ? fRetTemp : fRet;FreeLibrary(hl nst);return fRet;此函数主要用于删除 USBI nstallDriver()时创建的注册表信息,同样的它使用自己的函数接口 UnRegisterClientDriverlD()和 UnRegisterClientSettings()来做相应的处理。另外一个需要处理的注册的监控通知函数USBDeviceNotificatio ns ():extern "C" BOOL U

30、SBDeviceNotificati on s(LPVOID IpvNotifyParameter, DWORD dwCode, LPDWORD * dwl nfol, LPDWORD * dwl nfo2, LPDWORD * dwl nfo3,LPDWORD * dwl nfo4)CMouse * pMouse = (CMouse *)lpvNotifyParameter;switch(dwCode)case USB_CLOSE_DEVICE:/删除相关的资源。delete pMouse;return TRUE;return FALSE;USB鼠标的类的定义如下:class CMousep

31、ublic:CMouse:CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFu ncs, LPCUSB_lNTERFACE lp In terface);CMouse();BOOL In itialize();private:/传输完毕调用的回调函数static DWORD CALLBACK MouseTra nsferCompleteStub(LPVOID lpvNotifyParameter);/中断处理函数static ULONG CALLBACK CMouse:MouseThreadStub(PVOID con text);DWORD Mous

32、eTra nsferComplete();DWORD MouseThread();BOOL Submit In terrupt();BOOL Han dle In terrupt();BOOL m_fClos ing;BOOL m_fReadyForMouseEve nts;HANDLE m_hEve nt;HANDLE m_hThread;USB_HANDLE m_hDevice;USB_PIPE m_hI nterruptPipe;USB_TRANSFER m_hI nterruptTra nsfer;LPCUSB_FUNCS m_lpUsbF uncs;LPCUSB_INTERFACE

33、m_pI nterface;BOOL m_fPrevButto n1;BOOL m_fPrevButto n2;BOOL m_fPrevButto n3;/数据接受缓冲区。BYTE m_pbDataBuffer8;具体实现如下:/构造函数,初始化时调用CMouse:CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFu ncs,LPCUSB_INTERFACE lp In terface)m_fClosi ng = FALSE;m_fReadyForMouseEve nts = FALSE;m_hEve nt = NULL;m_hThread = NUL

34、L;m_hDevice = hDevice;m_hI nterruptPipe = NULL;m_hI nterruptTra nsfer = NULL;m_lpUsbF uncs = IpUsbF uncs; m_pl nteface = IpI nteface;m_fPrevButto n1 = FALSE;m_fPrevButto n2 = FALSE;m_fPrevButto n3 = FALSE;memset(m_pbDataBufer, 0, sizeof(m_pbDataBuffer);/析构函数,用于清除申请的资源。CMouse:CMouse()/通知系统去关闭相关的函数接口。

35、m_fClos ing = TRUE;/ Wake up the connection thread aga in and give it time to die. if (m_hEve nt != NULL)/通知关闭数据接受线程。SetEve nt(m_hEve nt);if (m_hThread != NULL)DWORD dwWaitReturn;dwWaitReturn = WaitForSi ngleObject(m_hThread, 1000);if (dwWaitReturn != WAIT_OBJECT_0)Termi nateThread(m_hThread, DWORD(

36、-1);CloseHa ndle(m_hThread);m_hThread = NULL;CloseHa ndle(m_hEve nt);m_hEve nt = NULL;if(m_hI nterruptTra nsfer)(*mpUsbF un cs->lpCloseTra nsfer)(m_hl nterruptTra nsfer);if(m_hl nterruptPipe)(*m_lpUsbF un cs->lpClosePipe)(m_hl nterruptPipe);/初始化USB鼠标驱动程序BOOL CMouse:I nitialize()LPCUSB_DEVICE I

37、pDevicel nfo = (*mpUsbFu ncs->lpGetDevicel nfo)(m_hDevice);/检测配置:USB鼠标应该只有一个中断管道if (m_p In terface->lpE ndpo in ts0.Descriptor.bmAttributes &USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_INTERRUPT)RETAILMSG(1,(TEXT(”!USBMouse: EP 0 wrong type (%u)!rn”),m_pln terface->lpE ndpo in ts0.Desc

38、riptor.bmAttributes);return FALSE;DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: EP O:MaxPacket: %u, I nterval: %urn"), m_pl nterface->lpE ndpoi nts0.Descriptor.wMaxPacketSize,m_p In terface->lpE ndpo in ts0.Descriptor.b In terval);m_hl nterruptPipe = (*m_lpUsbF un cs->lpOpe nPipe)(m_hDevice

39、,&m_p In terface->lpE ndpo in ts0.Descriptor);if (m_hl nterruptPipe = NULL) RETAILMSG(1,(TEXT("Mouse: Error ope ning in terrupt pipern");return (FALSE);m_hEve nt = CreateEve nt(NULL, FALSE, FALSE, NULL);if (m_hEve nt = NULL)RETAILMSG(1,(TEXT("USBMouse: Error on CreateEve nt for

40、 connect even trn"); return(FALSE);/创建数据接受线程m_hThread = CreateThread(0, 0, MouseThreadStub, this, 0, NULL);if (m_hThread = NULL)RETAILMSG(1,(TEXT("USBMouse: Error on CreateThreadr n"); return(FALSE);return(TRUE); /从USB鼠标设备中读出数据,产生相应的鼠标事件。BOOL CMouse:Submitl nterrupt()if(m_hl nterruptT

41、ra nsfer)(*mpUsbF un cs->lpCloseTra nsfer)(m_hl nterruptTra nsfer);/从USB鼠标PIPE中读数据m_hI nterruptTra nsfer = (*m_lpUsbF un cs->lpIssue In terruptTra nsfer)(m_h In terruptPipe, MouseTra nsferCompleteStub, this,USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK,表示读数据mi n(m _pl nterface->lpE ndpoi nts0.Des

42、criptor.wMaxPacketSize, sizeof(m_pbDataBuffer),m_pbDataBuffer,NULL);if (m_hI nterruptTra nsfer = NULL)DEBUGMSG(ZONE_ERRORL ”!USBMouse: Error in IssueI nterruptTra nsferr n"); return FALSE;elseDEBUGMSG(ZONE_TRANSFER,(L"USBMouse:Submitl nterrupt,Tra nsfer:Ox%Xrn", m_hI nterruptTra nsfer

43、);return TRUE;/处理鼠标中断传输的数据BOOL CMouse:Ha ndlel nterrupt()DWORD dwError;DWORD dwBytes;DWORD dwFlags = 0;INT dx = (sig ned char)m_pbDataBuffer1;INT dy = (sig ned char)m_pbDataBuffer2;BOOL fButto n1 = m_pbDataBufferO & 0x01 ? TRUE : FALSE;BOOL fButto n2 = m_pbDataBuffer0 & 0x02 ? TRUE : FALSE;B

44、OOL fButto n3 = m_pbDataBuffer0 & 0x04 ? TRUE : FALSE;if (!(*m_lpUsbF un cs->lpGetTra nsferStatus)(m_h In terruptTra nsfer,&dwBytes, &dwError)DEBUGMSG(ZONE_ERROR,(TEXT(”!USBMouse: Error in GetTra nsferStatus(0x%X)rn"), m_hI nterruptTra nsfer);return FALSE;elseDEBUGMSG(ZONE_TRANSF

45、ER,(TEXT("USBMouse:Ha ndlel nterrupt, hTra nsfer 0x%Xcomplete(%u bytes, Error:%X)rn"),m_hl nterruptTra nsfer,dwBytes,dwError);if (!Submit In terrupt()return FALSE;if(dwError != USB_NO_ERROR)DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error 0x%X in in terrupttran sferrn"),dwError);retur

46、n TRUE;if(dwBytes < 3)DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: In valid byte cnt %u from in terrupttran sferrn ”),dwBytes);return TRUE;if(dx | dy)dwFlags |= MOUSEEVENTF_MOVE;if(fButto n1 != m_fPrevButto n1)if(fButto n1)dwFlags |= MOUSEEVENTF_LEFTDOWN;elsedwFlags |= MOUSEEVENTF_LEFTUP;if(fButton

47、2 != m_fPrevButton2)if(fButto n2)dwFlags |= MOUSEEVENTF_RIGHTDOWN;elsedwFlags |= MOUSEEVENTF_RIGHTUP;if(fButton3 != m_fPrevButton3)if(fButto n3)dwFlags |= MOUSEEVENTF_MIDDLEDOWN;elsedwFlags |= MOUSEEVENTF_MIDDLEUP;m_fPrevButt on1 = fButto n1;m_fPrevButto n2 = fButto n2;m_fPrevButto n3 = fButto n3;DEBUGMSG(ZONE_EVENTS,(TEXT("USBMouse event: dx:%d, dy

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论