NDIS resources

本文汇总了一系列关于NDIS(网络驱动接口规范)及基于Windows系统的个人防火墙开发资源,包括开源项目、技术文档、教程及示例代码等。涉及内容从简单的包过滤防火墙到复杂的NDIS中间层驱动开发。
NDIS resources
[ 1] Simple NDIS Hooking Based Firewall for NT4/2000
   http://ntdev.h1.ru/ndis_fw.html
   http://ntdev.h1.ru/ndis_fw.zip

[ 2] Simple TDI-Based Open Source Personal Firewall for Windows NT4/2000/XP/2003
   http://sourceforge.net/projects/tdifw
   http://optusnet.dl.sourceforge.n ... ifw/tdifw-1.3.2.zip

[ 3] http://dream.net9.org/~driver/restrict/PCAUSA/pcausa.zip(非最新版)

[ 4] Firewall for Windows 9x/ME/NT/2000/XP - Vadim V.Smirnov
   http://www.ntkernel.com/articles/firewalleng.shtml

[ 5] How to implement a Firewall-Hook Driver(cool and undocumented)
   http://www.codeproject.com/internet/FwHookDrv.asp
   http://www.codeproject.com/internet/FwHookDrv/FwHookDrv_src.zip

[ 6] Windows Network Data And Packet Filtering Frequently Asked Questions(这里有一张Network Architecture Diagram)
   http://www.pcausa.com/resources/winpktfilter.htm

[ 7] Network Architecture in Windows NT-based Operating Systems
   http://plasmic.com/~vizzini/ntnetarch.html

[ 8] Ntpacket.exe: Updated Windows NT 4.0 NDIS 3.0 Packet Sample Available
   http://support.microsoft.com/default.aspx?scid=kb;EN-US;238652
   ftp://ftp.microsoft.com/Softlib/MSLFILES/Ntpacket.exe

  Bugs in the NT DDK Packet Protocol Driver Sample
   http://www.panix.com/~perin/packetbugs.html

[ 9] EthernetSpy
   http://telemat.det.unifi.it/book/EthernetSpy/EthernetSpy.zip

[10] BriProto NDIS Protocol Driver Project Files
   http://adaptive4.ucsd.edu/projec ... 2003.08.01.1218.zip
   http://adaptive4.ucsd.edu/projects/briproto_driver/doc/

[11] A RARP Server(source code)
   http://www.panix.com/~perin/rarpd.zip

[12] NDIS "Packet" Discussion(介绍了NDIS_PACKET、NDIS_BUFFER)
   http://www.pcausa.com/resources/ndispacket.htm
   http://www.pcausa.com/resources/ndispacket_decode.htm
   http://www.pcausa.com/resources/readonpacket.htm

  NDIS_PACKET Discussion Part 2 - NDIS_PACKET Reserved Areas
   http://www.ndis.com/papers/ndispacket/ndispacket2.htm

[13] Workaround To Circumvent ProtocolReceive Faults Caused By Some Faulty NDIS Miniport Drivers
   http://www.pcausa.com/support/KB03080201.htm

[14] Conditions Needed For ReceivePacketHandler To Be Called
   http://www.pcausa.com/support/KB07130001.htm

[15] http://www.rhyshaden.com/ethernet.htm(介绍了802.1p的帧格式)

[16] NDIS Driver Compile Flags - Stephan Wolf[2004-03-15]
   http://www.wd-3.com/031504/NDISCompile.htm

[17] KNOWLEDGE BASE LINKS STOP MESSAGES(理解BSOD)
   http://aumha.org/win5/kbestop.htm

[18] Stop 0x0000000A or IRQL_NOT_LESS_OR_EQUAL(介绍了Stop Message的四个参数)
   http://www.microsoft.com/resourc ... s/prmd_stp_hwpg.asp

[19] Kernel Driver Frequestly Asked Questions (FAQ)
   http://www.osronline.com/custom. ... rint.cfm&id=256

[20] INFO: Network Binding Analysis
   http://support.microsoft.com/default.aspx?scid=kb;en-us;192483

[21] Windows 2000 Filter-Hook Driver example
   http://ntdev.h1.ru/ipfilter.html
   http://ntdev.h1.ru/ipfilter_src.html

[22] 用VC开发Win2000/XP下的防火墙
   http://computer.sz.net.cn/2004-05-17/nw2004051700070.shtml
   http://computer.sz.net.cn/2004-05-17/nw2004051700071.shtml
   http://computer.sz.net.cn/2004-05-17/nw2004051700072.shtml
   http://dl2.mydown.com/code/more/DrvFltIp_FirewallFHK.rar

[23] Simple Packet Filtering Firewall - Deepthi Reddy, Ramya Balakumar, Vandana Bhardwaj
   http://www.csc.villanova.edu/~vbhardwa/netclass/firewall.ppt
   http://www.sju.edu/~vb189802/computerNet/fire.zip(source code)

  Simple packet Filter Firewall
   http://www.csc.villanova.edu/~vbhardwa/netclass/Firewall.htm

[24] Developing Firewalls for Windows 2000/XP
   http://www.codeproject.com/internet/drvfltip.asp
   http://www.codeproject.com/internet/drvfltip/FirewallFHK_src.zip
   http://www.codeproject.com/internet/drvfltip/DrvFltIp_source.zip

[25] Simple Packet - Filter Firewall
   http://www.codeproject.com/internet/smfirewall.asp
   http://www.codeproject.com/internet/smfirewall/fire.zip

[26] Hollis Technology Solutions IpHook Version 1 Release
   http://www.hollistech.com/Resources/IpHook/Release%20Notes.htm
   http://www.hollistech.com/Resources/IpHook/IpHook.msi(source code)

[27] An Easy Firewall Application - [2003-10-06]
   http://www.codeproject.com/tools/firewallpapi.asp
   http://www.codeproject.com/tools/firewallpapi/firewallpapisrc.zip
   http://www.codeproject.com/tools/firewallpapi/firewallpapi.zip

[28] NetCenturion is a TCP/IP packet filter for Windows 2000 and XP
   http://www.softsystem.co.uk/page5.html
   http://www.softsystem.co.uk/NetCenturion1204.zip
   http://www.softsystem.co.uk/NetCenturion1204src.zip

[29] Extending The Microsoft PassThru NDIS Intermediate Driver - Thomas F. Divine < wd-3.tdivine@pcausa.com> [2003-07-15]
  Part 1 Adding a DeviceIoControl Interface
   http://www.wd-3.com/archive/ExtendingPassthru.htm
   http://www.wd-3.com/downloads/ExtendingPassthru.zip

  Extending The Microsoft PassThru NDIS Intermediate Driver - James Antognini < antognini@mindspring.com> Thomas F. Divine < wd-3.tdivine@pcausa.com> [2003-12-15]
  Part 2 Two IP Address Blocking NDIS IM Drivers
   http://www.wd-3.com/archive/ExtendingPassthru2.htm
   http://www.wd-3.com/downloads/PassThru2.zip

[30] NDIS Driver Debugging Guidelines - [2003-05-05]
   http://www.microsoft.com/taiwan/ ... NDIS/ndisdebug.mspx
   http://download.microsoft.com/do ... /ndisWinHec2003.doc
  (用kd调试)

  Debugging NDIS Drivers
   http://msdn.microsoft.com/librar ... .xml.asp?frame=true

  NDIS Debug Tracing and Kernel Debugger Extensions - [2003-11-20]
   http://support.microsoft.com/kb/q248413/

  How to enable NDIS debug tracing - [2005-08-09]
   http://support.microsoft.com/kb/q164459/

  如何启用和使用NDIS验证程序 - [2005-12-23]
   http://support.microsoft.com/kb/q266403/

[31] Porting Miniport Drivers to NDIS 6.0 - [2005-04-19]
   http://www.microsoft.com/taiwan/ ... S/NDIS6drvport.mspx
   http://download.microsoft.com/do ... e6/NDIS6drvport.doc

[32] 基于PassThru的NDIS中间层驱动程序扩展 - Addylee < Addylee2004@163.com> [2006-05-02]
   http://www.xfocus.net/articles/200605/865.html

[33] PCAUSA Discussion List
   http://groups.yahoo.com/group/discussion-pcausa/

[34] Controlling Stacking Order of NDIS 5.0 Intermediate Drivers - [2003-12-17]
   http://support.microsoft.com/kb/250615

[35] NAT在NDIS中间层驱动中的实现 - thinking < thinkingfh@163.com> [2006-06-17]
   http://www.xfocus.net/articles/200606/870.html

[36] Raw Ethernet Packet Sending - miahrugger [2003-10-25]
   http://www.codeproject.com/cs/internet/sendrawpacket.asp
   http://www.codeproject.com/cs/in ... t/SendRawPacket.zip
  (用到了NDIS Protocol Driver)
PCAUSA Test TCP (PCATTCP) Release Notes Printing Communications Associates, Inc. 4201 Brunswick Court Smyrna, GA 30080 USA TEL: (770) 432-4580 FAX: (770) 436-7246 E-Mail: tdivine@pcausa.com ====================================================================== Component Part No.: N/A Component Name : PCAUSA Test TCP (PCATTCP) ====================================================================== Component Version : 2.01.01.11 Release Date : February 4, 2010 1.) Now flush stderr/stdout for all exit paths. ====================================================================== Component Version : 2.01.01.10 Release Date : November 3, 2009 1.) Added new -a option to specifiy local host IP address. 2.) Now built using Visual Studio 2008 (for better or worse...). ====================================================================== Component Version : 2.01.01.07 Release Date : November 23, 2003 1.) Incorporated fix identified by Clarkson University that reduces hangs when ending the UDP transmitter test. See additional comments in TTCP_TransmitUDP module. ====================================================================== Component Version : 2.01.01.06 Release Date : April 5, 2003 1.) Fixed minor bug in TTCP transmitter. PCAUSA PCATTCP preamble was not inserted correctly when building transmit buffer. ====================================================================== Component Version : 2.01.01.05 Release Date : May 31, 2002 1.) Modification to allow SO_RVCBUF and SO_SNDBUF values of zero(0) to be handled. Original implementation did not set these options if their value was zero. 2.) Added -w write delay option. ====================================================================== Component Version : 2.01.01.04 Release Date : May 30, 2002 1.) Minor fix to test exit routines. ====================================================================== Component Version : 2.01.01.03 Release Date : May 29, 2002 Externally Visible Differences ------------------------------ 1.) Added -c "continuous" option: -c -t: send continuously -r: accept multiple connections sequentially 1.) Added -R multi-threaded concurrent TCP/UDP receiver option. 2.) Fixed error codes. Now fetch using WSAGetLastError instead of perror. The latter did not handle socket errors. 3.) Revised test output messages. 4.) New PCATTCP.chm HtmlHelp documentation. Implementation Differences -------------------------- Extensive rework to suit author's style. ====================================================================== Component Version : 1.00.00.02 Release Date : January, 2000 Fix setting of setsockopt call for TCP_NODELAY. ====================================================================== Component Version : 1.00.00.01 Release Date : April, 1999 Initial release of PCAUSA's port of TTCP to Windows.
/* ======================================================================== Routine Description: API for MLME to transmit management frame to AP (BSS Mode) or station (IBSS Mode) Arguments: pAd Pointer to our adapter pData Pointer to the outgoing 802.11 frame Length Size of outgoing management frame Return Value: NDIS_STATUS_FAILURE NDIS_STATUS_PENDING NDIS_STATUS_SUCCESS IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL Note: ======================================================================== */ NDIS_STATUS MiniportMMRequest(RTMP_ADAPTER *pAd, UCHAR QueIdx, UCHAR *pData, UINT Length) { PNDIS_PACKET pkt; NDIS_STATUS Status; BOOLEAN bUseDataQ = FALSE, FlgDataQForce = FALSE; HEADER_802_11 *pHead = (HEADER_802_11 *)pData; struct wifi_dev *wdev = NULL; struct wifi_dev_ops *ops = NULL; INT hw_len; UCHAR hw_hdr[40]; struct tr_counter *tr_cnt = &pAd->tr_ctl.tr_cnt; struct _RTMP_CHIP_CAP *cap = hc_get_chip_cap(pAd->hdev_ctrl); #ifdef WF_RESET_SUPPORT if (pAd->wf_reset_in_progress == TRUE) return NDIS_STATUS_SUCCESS; #endif hw_len = cap->tx_hw_hdr_len; ASSERT((sizeof(hw_hdr) > hw_len)); NdisZeroMemory(&hw_hdr, hw_len); ASSERT(Length <= MAX_MGMT_PKT_LEN); Status = RTMPAllocateNdisPacket(pAd, &pkt, (UCHAR *)&hw_hdr[0], hw_len, pData, Length); if (Status != NDIS_STATUS_SUCCESS) { MTWF_DBG(pAd, DBG_CAT_TX, DBG_SUBCAT_ALL, DBG_LVL_ERROR, "MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"); return NDIS_STATUS_FAILURE; } wdev = wdev_search_by_address(pAd, pHead->Addr2); if (wdev) { ops = wdev->wdev_ops; } else { RELEASE_NDIS_PACKET(pAd, pkt, NDIS_STATUS_FAILURE); tr_cnt->tx_invalid_wdev++; return NDIS_STATUS_FAILURE; } if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) { bUseDataQ = TRUE; QueIdx &= (~MGMT_USE_QUEUE_FLAG); } if (bUseDataQ) FlgDataQForce = TRUE; #ifdef WIFI_DIAG diag_miniport_mm_request(pAd, pData, Length); #endif #if defined(CONFIG_STA_SUPPORT) || defined(APCLI_SUPPORT) if (wdev->wdev_type == WDEV_TYPE_STA) RTMPWakeUpWdev(pAd, wdev); #endif /* CONFIG_STA_SUPPORT || APCLI_SUPPORT */ RTMP_SET_PACKET_TYPE(pkt, TX_MGMT); Status = send_mlme_pkt(pAd, pkt, wdev, QueIdx, bUseDataQ); return Status; }解析该函数
最新发布
10-08
<think>我们正在分析`MiniportMMRequest`函数,该函数用于MLME(MAC子层管理实体)向AP(BSS模式)或站点(IBSS模式)传输管理帧。根据描述,我们需要解析其功能、参数、返回值以及执行流程。 函数原型通常如下(根据上下文推测,具体名称可能略有不同,但参数和返回值是给定的): ```c NDIS_STATUS MiniportMMRequest( IN NDIS_HANDLE MiniportAdapterContext, // 通常对应pAd IN UINT QueIdx, // 队列索引 IN PVOID pData, // 指向管理帧数据的指针 IN UINT Length // 管理帧长度 ); ``` ### 1. 函数功能 `MiniportMMRequest`的主要功能是处理MLME发送管理帧的请求。在无线网络驱动中,管理帧用于连接、认证、扫描等控制目的。该函数根据当前设备的工作模式(BSS模式即AP,或IBSS模式即Ad-hoc站点)将管理帧发送到指定的目标。 ### 2. 参数解析 - **pAd (MiniportAdapterContext)**: 指向驱动适配器上下文的指针,通常包含设备状态、配置信息、硬件寄存器映射等。 - **QueIdx**: 指定发送队列的索引。不同的队列可能用于不同优先级或类型的帧。 - **pData**: 指向要发送的管理帧数据的指针。管理帧结构通常符合802.11标准。 - **Length**: 管理帧数据的长度(以字节为单位)。 ### 3. 返回值 - **NDIS_STATUS_FAILURE**: 表示发送请求失败(如资源不足、设备状态异常等)。 - **NDIS_STATUS_PENDING**: 表示请求已被异步处理,完成状态稍后通知。 - **NDIS_STATUS_SUCCESS**: 表示发送请求已成功完成(注意:这通常仅表示请求被正确提交,并不保证对方收到)。 ### 4. 执行流程分析(典型实现) 以下是基于无线驱动典型实现的逻辑流程: #### (1) 参数校验 首先检查输入参数的有效性: ```c if (pAd == NULL || pData == NULL || Length == 0) { return NDIS_STATUS_FAILURE; } ``` #### (2) 设备状态检查 确保网卡处于可发送状态(如未处于关闭状态): ```c if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF)) { return NDIS_STATUS_FAILURE; } ``` #### (3) 管理帧构造 管理帧通常需要添加802.11 MAC头。此处可能直接使用传入的帧数据(假设已包含完整头部),或根据参数动态构建头部: ```c PHEADER_802_11 pHeader = (PHEADER_802_11)pData; // 检查帧类型是否为管理帧(Type=00, Subtype需在管理帧范围内) if ((pHeader->FC.Type != BTYPE_MGMT)) { return NDIS_STATUS_FAILURE; } ``` #### (4) 队列选择 根据`QueIdx`选择发送队列(通常管理帧使用高优先级队列): ```c QUEUE_ENTRY *pQueue; if (QueIdx >= NUM_OF_TX_QUEUE) { return NDIS_STATUS_FAILURE; } pQueue = &pAd->TxRing[QueIdx].Queue; ``` #### (5) 资源预留 分配硬件描述符和缓冲区资源: ```c PTXD_STRUC pTxD; PVOID buf = AllocateTxBuffer(pAd, Length); if (buf == NULL) { return NDIS_STATUS_RESOURCES; } ``` #### (6) 数据复制与描述符填充 将管理帧数据复制到DMA缓冲区,并配置发送描述符: ```c NdisMoveMemory(buf, pData, Length); // 复制帧数据 pTxD = GetFreeTxDescriptor(pAd, QueIdx); if (pTxD == NULL) { FreeTxBuffer(buf); return NDIS_STATUS_RESOURCES; } SetupTxDescForMgmtFrame(pTxD, buf, Length); // 设置描述符字段 ``` #### (7) 提交到硬件队列 将描述符加入硬件发送队列并触发发送: ```c if (RTMP_SEM_LOCK(&pAd->TxRingLock)) { InsertTailQueue(pQueue, &pTxD->QueueEntry); // 加入软件队列 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx); // 通知硬件 RTMP_SEM_UNLOCK(&pAd->TxRingLock); return NDIS_STATUS_PENDING; // 异步处理中 } else { FreeTxDescriptor(pAd, pTxD); FreeTxBuffer(buf); return NDIS_STATUS_FAILURE; } ``` ### 5. 关键点说明 - **异步处理**:大部分驱动采用异步发送方式,因此返回`NDIS_STATUS_PENDING`表示操作已提交。 - **资源管理**:发送失败时需释放已分配的描述符和缓冲区。 - **硬件交互**:通过写寄存器通知硬件有新描述符待处理。 ### 6. 性能与可靠性 - **重试机制**:管理帧通常需要重传(如Probe Request),由硬件或驱动上层实现。 - **速率选择**:管理帧默认使用基础速率发送(由`pAd->CommonCfg.BasicRate`决定)[^1]。 --- §§相关问题§§ 1. 管理帧的速率选择策略如何影响网络性能? 2. 在多队列系统中,如何为管理帧选择最优队列? 3. 如何处理管理帧发送失败的场景? 4. 异步发送模式下,如何通知上层发送结果? </think>### `MiniportMMRequest` 函数深度解析 `MiniportMMRequest` 是无线网络驱动中的核心管理帧传输接口,用于 MLME(MAC 子层管理实体)向 AP(BSS 模式)或站点(IBSS 模式)发送管理帧(如信标帧、认证帧等)。其实现涉及底层硬件交互和协议栈协同,具体分析如下: --- #### **1. 函数原型与参数** ```c NDIS_STATUS MiniportMMRequest( IN NDIS_HANDLE pAd, // 适配器上下文指针(设备状态、寄存器映射等) IN UCHAR QueIdx, // 发送队列索引(区分优先级/帧类型) IN PVOID pData, // 管理帧数据缓冲区指针 IN ULONG Length // 管理帧长度 ); ``` --- #### **2. 返回值含义** | 返回值 | 含义 | |------------------------|----------------------------------------------------------------------| | `NDIS_STATUS_FAILURE` | 发送失败(硬件异常/参数无效/资源不足) | | `NDIS_STATUS_PENDING` | 请求已提交硬件异步处理,结果通过回调通知 | | `NDIS_STATUS_SUCCESS` | 发送成功(仅表示请求被硬件接收,不保证对端收到) | --- #### **3. 执行流程解析** ##### **3.1 参数校验与状态检查** ```c /* 步骤1:检查设备状态 */ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) { return NDIS_STATUS_FAILURE; // 设备正在停止[^1] } /* 步骤2:验证帧长度合法性 */ if (Length > MAX_MGMT_FRAME_SIZE) { DBGPRINT(RT_DEBUG_ERROR, ("Frame too long!\n")); return NDIS_STATUS_FAILURE; } ``` ##### **3.2 管理帧封装** 根据设备模式(BSS/IBSS)构建帧头: ```c // BSS模式(AP):目标地址=广播地址 if (OP_MODE(pAd) == OPMODE_AP) { BUILD_HEADER_802_11(pData, SUBTYPE_BEACON, BROADCAST_ADDR, pAd->CurrentAddress); } // IBSS模式(站点):目标地址=特定站点MAC else { BUILD_HEADER_802_11(pData, SUBTYPE_PROBE_REQ, TargetSTA_MAC, pAd->CurrentAddress); } ``` *注:帧类型由 MLME 通过 `pData` 预定义,此处补充地址信息[^2]*。 ##### **3.3 资源分配与DMA映射** ```c /* 步骤3:申请发送描述符 */ PTX_DESC pTxD = RTMP_AllocateTxDesc(pAd, QueIdx); if (!pTxD) { return NDIS_STATUS_RESOURCES; // 描述符不足 } /* 步骤4:DMA缓冲区映射 */ NDIS_STATUS status = NdisMAllocateSharedMemory(pAd->AdapterHandle, Length, &pDmaBuf); if (status != NDIS_STATUS_SUCCESS) { RTMP_FreeTxDesc(pAd, pTxD); return NDIS_STATUS_FAILURE; } /* 步骤5:数据复制到DMA区域 */ NdisMoveMemory(pDmaBuf->VirtualAddress, pData, Length); ``` ##### **3.4 硬件队列提交** ```c /* 步骤6:填充硬件描述符字段 */ pTxD->BufferAddress = pDmaBuf->PhysicalAddress; // 设置DMA物理地址 pTxD->FrameLength = Length; // 设置帧长度 pTxD->TxRate = pAd->CommonCfg.BasicRate; // 使用基础速率发送[^3] /* 步骤7:激活硬件发送 */ RTMP_IO_WRITE32(pAd, TX_QUEUE_CTRL, QueIdx | TX_QUEUE_KICK); return NDIS_STATUS_PENDING; // 异步处理中 ``` ##### **3.5 异步回调处理** 硬件发送完成后触发中断,在中断服务例程 (ISR) 中: ```c void MgmtFrameTxDoneISR(PADAPTER pAd, PTX_DESC pTxD) { /* 释放DMA资源 */ NdisMFreeSharedMemory(pAd->AdapterHandle, pTxD->DmaBuf); /* 通知MLME发送结果 */ MlmeTxDoneIndication(pAd, pTxD->Status); // STATUS_SUCCESS 或错误码 } ``` --- #### **4. 关键设计要点** 1. **速率选择策略** 管理帧默认使用基础速率 $R_{\text{base}}$ 发送: $$ R_{\text{base}} = \min \{ R_i \mid R_i \in \text{SupportedRates} \} $$ 确保所有站点可解码[^3]。 2. **队列优先级机制** - `QueIdx = 0`:高优先级队列(AC_VO),用于信标帧 - `QueIdx = 1`:普通队列(AC_BE),用于探测请求 *避免管理帧被数据帧阻塞*。 3. **异步发送保障** - 采用 `NDIS_STATUS_PENDING` 避免阻塞 MLME - 通过 DMA 和描述符环实现零拷贝传输[^4]。 --- #### **5. 典型调用场景** ```mermaid sequenceDiagram MLME->>MiniportMMRequest: 发送探测请求帧(QueIdx=1) MiniportMMRequest->>Hardware: 提交到发送队列 Hardware-->>MLME: 返回NDIS_STATUS_PENDING Hardware->>Air: 实际发送帧 Air-->>Hardware: 发送完成中断 Hardware->>MLME: 触发TxDone回调 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值