WinCE下存储设备的遍历以及磁盘分区的格式化、扫描和碎片整理类

原文地址::http://blog.csdn.net/werocpp/article/details/5466755


 由于需要在WinCE下对某个磁盘分区进行格式化,在网上查找了相关资料整理出了一个类与大家分享,不足之处请指教。

[cpp]  view plain copy
  1. /******************************************************************** 
  2.     created:    2010/03/17 
  3.     created:    17:3:2010   14:14 
  4.     filename:   f:/个人资料_zwf/自己的源代码/CeFormatTools/CeFormatTools/CeStoreManager.h 
  5.     file path:  f:/个人资料_zwf/自己的源代码/CeFormatTools/CeFormatTools 
  6.     file base:  CeStoreManager 
  7.     file ext:   h 
  8.     author:     zhangwf 
  9.      
  10.     purpose:    WINCE磁盘设备管理(遍历及格式化等操作) 
  11. *********************************************************************/  
  12. #ifndef _CE_STORE_MANAGER_H_  
  13. #define _CE_STORE_MANAGER_H_  
  14. //  
  15. #include <Storemgr.h>  
  16. #include <fatutil.h>  
  17. #include <vector>  
  18. using namespace std;  
  19. typedef vector<STOREINFO> CStoreInfoArray;  
  20. typedef vector<PARTINFO> CPartInfoArray;  
  21. //  
  22. class CeStoreManager  
  23. {  
  24. public:  
  25.     // 构造析构函数  
  26.     CeStoreManager(BOOL bLoadAllStorePart=FALSE);  
  27.     ~CeStoreManager();  
  28.   
  29. public:  
  30.     // 对分区的操作接口  
  31.     // 格式化一个分区  
  32.     BOOL FormatPart(HANDLE hPart, PFN_PROGRESS pfnProgress=NULL);  
  33.     BOOL FormatPart(LPCTSTR szDeviceName, LPCTSTR szPartName, PFN_PROGRESS pfnProgress=NULL);  
  34.   
  35.     // 扫描一个分区  
  36.     BOOL ScanPart(HANDLE hPart, PFN_PROGRESS pfnProgress=NULL);  
  37.     BOOL ScanPart(LPCTSTR szDeviceName, LPCTSTR szPartName, PFN_PROGRESS pfnProgress=NULL);  
  38.   
  39.     // 对一个分区进行碎片整理  
  40.     BOOL DefragPart(HANDLE hPart, PFN_PROGRESS pfnProgress=NULL);  
  41.     BOOL DefragPart(LPCTSTR szDeviceName, LPCTSTR szPartName, PFN_PROGRESS pfnProgress=NULL);  
  42.   
  43. public:  
  44.     // 接口函数(遍历所有存储设备的分区)  
  45.     // 加载所有存储设备的所有分区信息,下面所有的接口建立在调用该接口后的基础上(或构造函数中指定了加载)  
  46.     BOOL LoadAllStorePart();  
  47.   
  48.     // 获得存储设备数量  
  49.     long GetStoreCounts();  
  50.   
  51.     // 获得某个存储设备的信息  
  52.     BOOL GetStoreInfo(long storeIndex, STOREINFO &storeInfo);  
  53.   
  54.     // 获得某个存储设备上的分区数量  
  55.     long GetStorePartCounts(long storeIndex);  
  56.   
  57.     // 获得某个存储设备上的某个分区信息  
  58.     BOOL GetStorePartInfo(long storeIndex, long partIndex, PARTINFO &partInfo);  
  59.   
  60.     // 格式化某个存储设备上的某个分区  
  61.     BOOL FormatPart(long storeIndex, long partIndex, PFN_PROGRESS pfnProgress=NULL);  
  62.   
  63.     // 扫描某个存储设备上的某个分区  
  64.     BOOL ScanPart(long storeIndex, long partIndex, PFN_PROGRESS pfnProgress=NULL);  
  65.   
  66.     // 对某个存储设备上的某个分区进行碎片整理  
  67.     BOOL DefragPart(long storeIndex, long partIndex, PFN_PROGRESS pfnProgress=NULL);  
  68.   
  69. private:  
  70.     // 私有函数  
  71.     // 加载所有存储设备  
  72.     BOOL LoadAllStore();  
  73.   
  74.     // 加载一个存储设备上所有的分区信息  
  75.     BOOL LoadStorePartition(LPCTSTR storeDeviceName, CPartInfoArray &storePartArray);  
  76.   
  77.     // 获得安全的动态库实例  
  78.     BOOL GetSafeDllInstance();  
  79.   
  80.     // 释放动态库  
  81.     void FreeDllInstance();  
  82.   
  83.     // 获得安全存储设备索引  
  84.     BOOL GetSafeIndex(long storeIndex);  
  85.     BOOL GetSafeIndex(long storeIndex, long partIndex);  
  86.   
  87. private:  
  88.     CStoreInfoArray m_StoreArray;        // 存放所有存储设备信息  
  89.     vector<CPartInfoArray> m_PartArray;  // 存放所有存储设备的所有分区信息  
  90.     HINSTANCE m_hUtilDll;      // 加载动态库FATUTIL.DLL的实例句柄  
  91.   
  92. };  
  93. //  
  94. #endif  

 

下面给出源文件

[cpp]  view plain copy
  1. /******************************************************************** 
  2.     created:    2010/03/17 
  3.     created:    17:3:2010   14:15 
  4.     filename:   f:/个人资料_zwf/自己的源代码/CeFormatTools/CeFormatTools/CeStoreManager.cpp 
  5.     file path:  f:/个人资料_zwf/自己的源代码/CeFormatTools/CeFormatTools 
  6.     file base:  CeStoreManager 
  7.     file ext:   cpp 
  8.     author:     zhangwf 
  9.      
  10.     purpose:    WINCE磁盘设备管理(遍历及格式化等操作) 
  11. *********************************************************************/  
  12. //  
  13. #include <Windows.h>  
  14. #include "CeStoreManager.h"  
  15. //  
  16. typedef DWORD (*PFN_MY_FORMATVOLUME)(HANDLE hVolume, PDISK_INFO pdi, PFORMAT_OPTIONS pfo, PFN_PROGRESS pfnProgress,PFN_MESSAGE pfnMessage);  
  17. typedef BOOL (*PFN_MY_SCANVOLUME)(HANDLE hVolume, PDISK_INFO pdi, PSCAN_OPTIONS pso, PFN_PROGRESS pfnProgress, PFN_MESSAGE pfnMessage);  
  18. typedef BOOL (*PFN_MY_DEFRAGVOLUME)(HANDLE hVolume, PDISK_INFO pdi, PDEFRAG_OPTIONS pdo, PFN_PROGRESS pfnProgress, PFN_MESSAGE pfnMessage);  
  19.   
  20. //  
  21. // 构造函数  
  22. CeStoreManager::CeStoreManager(BOOL bLoadAllStorePart)  
  23. {  
  24.     // 初始化变量  
  25.     m_hUtilDll = NULL;  
  26.     if (bLoadAllStorePart == TRUE)  
  27.     {  
  28.         LoadAllStorePart();  
  29.     }  
  30. }  
  31.   
  32. // 析构函数  
  33. CeStoreManager::~CeStoreManager()  
  34. {  
  35.     // 释放动态库  
  36.     FreeDllInstance();  
  37. }  
  38.   
  39. //  
  40. // 接口函数  
  41. // 格式化一个分区(传入分区句柄及回调进度函数)  
  42. BOOL CeStoreManager::FormatPart(HANDLE hPart, PFN_PROGRESS pfnProgress)  
  43. {  
  44.     // 获得安全的DLL实例  
  45.     if (GetSafeDllInstance() == FALSE)  
  46.     {  
  47.         return FALSE;  
  48.     }  
  49.   
  50.     // 取得函数地址  
  51.     PFN_MY_FORMATVOLUME pfnFormatVolume = (PFN_MY_FORMATVOLUME)GetProcAddress(m_hUtilDll, TEXT("FormatVolume"));  
  52.     if(pfnFormatVolume==NULL)  
  53.     {  
  54.         printf("Get FormatVolumeProc Address Error!/n");  
  55.         return FALSE;  
  56.     }  
  57.   
  58.     //must dismount the partition  
  59.     DismountPartition(hPart);  
  60.   
  61.     // 格式化  
  62.     if(pfnFormatVolume(hPart, NULL, NULL, pfnProgress, NULL) != ERROR_SUCCESS)  
  63.     {  
  64.         printf("Format Volume Error!/n");  
  65.         MountPartition(hPart);  
  66.         return FALSE;  
  67.     }  
  68.   
  69.     //finished format, mount partition  
  70.     MountPartition(hPart);  
  71.   
  72.     // 格式化成功  
  73.     printf("Format Success!/n");  
  74.     return TRUE;  
  75. }  
  76.   
  77. // 格式化一个分区(传入存储设备名字和分区名字及回调进度函数)  
  78. BOOL CeStoreManager::FormatPart(LPCTSTR szDeviceName, LPCTSTR szPartName, PFN_PROGRESS pfnProgress)  
  79. {  
  80.     // 打开存储设备  
  81.     HANDLE hStore = OpenStore(szDeviceName);  
  82.     if (hStore == INVALID_HANDLE_VALUE)  
  83.     {  
  84.         return FALSE;  
  85.     }  
  86.   
  87.     // 打开分区  
  88.     HANDLE hPart = OpenPartition(hStore, szPartName);  
  89.     CloseHandle(hStore);  
  90.     if (hPart == INVALID_HANDLE_VALUE)  
  91.     {  
  92.         return FALSE;  
  93.     }  
  94.   
  95.     // 格式化该分区  
  96.     BOOL bResult = FormatPart(hPart, pfnProgress);  
  97.   
  98.     // 关闭分区句柄  
  99.     CloseHandle(hPart);  
  100.   
  101.     // 返回结果  
  102.     return bResult;  
  103. }  
  104.   
  105. // 扫描一个分区  
  106. BOOL CeStoreManager::ScanPart(HANDLE hPart, PFN_PROGRESS pfnProgress)  
  107. {  
  108.     // 获得安全的DLL实例  
  109.     if (GetSafeDllInstance() == FALSE)  
  110.     {  
  111.         return FALSE;  
  112.     }  
  113.   
  114.     // 取得函数地址  
  115.     PFN_MY_SCANVOLUME pfnScanVolume = (PFN_MY_SCANVOLUME)GetProcAddress(m_hUtilDll, TEXT("ScanVolume"));  
  116.     if(pfnScanVolume==NULL)  
  117.     {  
  118.         printf("Get ScanVolumeProc Address Error!/n");  
  119.         return FALSE;  
  120.     }  
  121.   
  122.     //must dismount the partition  
  123.     DismountPartition(hPart);  
  124.   
  125.     // 扫描分区  
  126.     if(pfnScanVolume(hPart, NULL, NULL, pfnProgress, NULL) == FALSE)  
  127.     {  
  128.         printf("Scan Volume Error!/n");  
  129.         MountPartition(hPart);  
  130.         return FALSE;  
  131.     }  
  132.   
  133.     //finished format, mount partition  
  134.     MountPartition(hPart);  
  135.   
  136.     // 扫描成功  
  137.     printf("Scan Success!/n");  
  138.     return TRUE;  
  139. }  
  140.   
  141. // 扫描一个分区  
  142. BOOL CeStoreManager::ScanPart(LPCTSTR szDeviceName, LPCTSTR szPartName, PFN_PROGRESS pfnProgress)  
  143. {  
  144.     // 打开存储设备  
  145.     HANDLE hStore = OpenStore(szDeviceName);  
  146.     if (hStore == INVALID_HANDLE_VALUE)  
  147.     {  
  148.         return FALSE;  
  149.     }  
  150.   
  151.     // 打开分区  
  152.     HANDLE hPart = OpenPartition(hStore, szPartName);  
  153.     CloseHandle(hStore);  
  154.     if (hPart == INVALID_HANDLE_VALUE)  
  155.     {  
  156.         return FALSE;  
  157.     }  
  158.   
  159.     // 扫描该分区  
  160.     BOOL bResult = ScanPart(hPart, pfnProgress);  
  161.   
  162.     // 关闭分区句柄  
  163.     CloseHandle(hPart);  
  164.   
  165.     // 返回结果  
  166.     return bResult;  
  167. }  
  168.   
  169. // 对一个分区进行碎片整理  
  170. BOOL CeStoreManager::DefragPart(HANDLE hPart, PFN_PROGRESS pfnProgress)  
  171. {  
  172.     // 获得安全的DLL实例  
  173.     if (GetSafeDllInstance() == FALSE)  
  174.     {  
  175.         return FALSE;  
  176.     }  
  177.   
  178.     // 取得函数地址  
  179.     PFN_MY_DEFRAGVOLUME pfnDefragVolume = (PFN_MY_DEFRAGVOLUME)GetProcAddress(m_hUtilDll, TEXT("DefragVolume"));  
  180.     if(pfnDefragVolume==NULL)  
  181.     {  
  182.         printf("Get DefragVolumeProc Address Error!/n");  
  183.         return FALSE;  
  184.     }  
  185.   
  186.     //must dismount the partition  
  187.     DismountPartition(hPart);  
  188.   
  189.     // 对分区进行碎片整理  
  190.     if(pfnDefragVolume(hPart, NULL, NULL, pfnProgress, NULL) == FALSE)  
  191.     {  
  192.         printf("Defrag Volume Error!/n");  
  193.         MountPartition(hPart);  
  194.         return FALSE;  
  195.     }  
  196.   
  197.     //finished format, mount partition  
  198.     MountPartition(hPart);  
  199.   
  200.     // 碎片整理成功  
  201.     printf("Defrag Success!/n");  
  202.     return TRUE;  
  203.   
  204. }  
  205.   
  206. // 对该分区进行碎片整理  
  207. BOOL CeStoreManager::DefragPart(LPCTSTR szDeviceName, LPCTSTR szPartName, PFN_PROGRESS pfnProgress)  
  208. {  
  209.     // 打开存储设备  
  210.     HANDLE hStore = OpenStore(szDeviceName);  
  211.     if (hStore == INVALID_HANDLE_VALUE)  
  212.     {  
  213.         return FALSE;  
  214.     }  
  215.   
  216.     // 打开分区  
  217.     HANDLE hPart = OpenPartition(hStore, szPartName);  
  218.     CloseHandle(hStore);  
  219.     if (hPart == INVALID_HANDLE_VALUE)  
  220.     {  
  221.         return FALSE;  
  222.     }  
  223.   
  224.     // 对该分区进行碎片整理  
  225.     BOOL bResult = DefragPart(hPart, pfnProgress);  
  226.   
  227.     // 关闭分区句柄  
  228.     CloseHandle(hPart);  
  229.   
  230.     // 返回结果  
  231.     return bResult;  
  232. }  
  233.   
  234. // 加载所有存储设备所有分区  
  235. BOOL CeStoreManager::LoadAllStorePart()  
  236. {  
  237.     // 加载所有存储设备  
  238.     if (LoadAllStore() == FALSE)  
  239.     {  
  240.         return FALSE;  
  241.     }  
  242.   
  243.     // 清除上次数据  
  244.     m_PartArray.clear();  
  245.   
  246.     // 遍历每一个设备加载其所有分区  
  247.     CPartInfoArray curPartArray;  
  248.     for (size_t storeIndex=0; storeIndex<m_StoreArray.size(); storeIndex++)  
  249.     {  
  250.         if (LoadStorePartition(m_StoreArray[storeIndex].szDeviceName, curPartArray) == TRUE)  
  251.         {  
  252.             m_PartArray.push_back(curPartArray);  
  253.         }  
  254.     }  
  255.   
  256.     // 加载成功  
  257.     return TRUE;  
  258. }  
  259.   
  260. // 获得存储设备数量  
  261. long CeStoreManager::GetStoreCounts()  
  262. {  
  263.     return (long)m_StoreArray.size();  
  264. }  
  265.   
  266. // 获得某个存储设备的信息  
  267. BOOL CeStoreManager::GetStoreInfo(long storeIndex, STOREINFO &storeInfo)  
  268. {  
  269.     if (storeIndex<0 || storeIndex>=GetStoreCounts())  
  270.     {  
  271.         return FALSE;  
  272.     }  
  273.   
  274.     storeInfo = m_StoreArray[storeIndex];  
  275.     return TRUE;  
  276. }  
  277.   
  278. // 获得某个存储设备上的分区数量  
  279. long CeStoreManager::GetStorePartCounts(long deviceIndex)  
  280. {  
  281.     if (deviceIndex<0 || deviceIndex>=(long)m_PartArray.size())  
  282.     {  
  283.         return 0;  
  284.     }  
  285.   
  286.     return (long)m_PartArray[deviceIndex].size();  
  287. }  
  288.   
  289. // 获得某个存储设备上的某个分区信息  
  290. BOOL CeStoreManager::GetStorePartInfo(long storeIndex, long partIndex, PARTINFO &partInfo)  
  291. {  
  292.     // 判断存储设备索引有效性  
  293.     if (storeIndex<0 || storeIndex>=(long)m_PartArray.size())  
  294.     {  
  295.         return FALSE;  
  296.     }  
  297.   
  298.     // 判断分区索引有效性  
  299.     if (partIndex<0 || partIndex>=(long)m_PartArray[storeIndex].size())  
  300.     {  
  301.         return FALSE;  
  302.     }  
  303.   
  304.     // 取得分区信息  
  305.     partInfo = m_PartArray[storeIndex].at(partIndex);  
  306.     return TRUE;  
  307. }  
  308.   
  309. // 格式化某个存储设备上的某个分区  
  310. BOOL CeStoreManager::FormatPart(long storeIndex, long partIndex, PFN_PROGRESS pfnProgress)  
  311. {  
  312.     // 索引不安全  
  313.     if (GetSafeIndex(storeIndex, partIndex) == FALSE)  
  314.     {  
  315.         return FALSE;  
  316.     }  
  317.   
  318.     // 格式化分区  
  319.     return FormatPart(m_StoreArray[storeIndex].szDeviceName, m_PartArray[storeIndex].at(partIndex).szPartitionName, pfnProgress);  
  320. }  
  321.   
  322. // 扫描某个存储设备上的某个分区  
  323. BOOL CeStoreManager::ScanPart(long storeIndex, long partIndex, PFN_PROGRESS pfnProgress)  
  324. {  
  325.     // 索引不安全  
  326.     if (GetSafeIndex(storeIndex, partIndex) == FALSE)  
  327.     {  
  328.         return FALSE;  
  329.     }  
  330.   
  331.     // 扫描该分区  
  332.     return ScanPart(m_StoreArray[storeIndex].szDeviceName, m_PartArray[storeIndex].at(partIndex).szPartitionName, pfnProgress);  
  333. }  
  334.   
  335. // 对某个存储设备上的某个分区进行碎片整理  
  336. BOOL CeStoreManager::DefragPart(long storeIndex, long partIndex, PFN_PROGRESS pfnProgress)  
  337. {  
  338.     // 索引不安全  
  339.     if (GetSafeIndex(storeIndex, partIndex) == FALSE)  
  340.     {  
  341.         return FALSE;  
  342.     }  
  343.   
  344.     // 对该分区进行碎片整理  
  345.     return DefragPart(m_StoreArray[storeIndex].szDeviceName, m_PartArray[storeIndex].at(partIndex).szPartitionName, pfnProgress);  
  346. }  
  347. //  
  348. // 私有函数  
  349. // 加载所有存储设备  
  350. BOOL CeStoreManager::LoadAllStore()  
  351. {  
  352.     // 清除上次数据  
  353.     m_StoreArray.clear();  
  354.   
  355.     // 查找第一个存储设备  
  356.     STOREINFO StoreInfo={0};   
  357.     StoreInfo.cbSize = sizeof(StoreInfo);  
  358.     HANDLE hFirstStore = FindFirstStore(&StoreInfo);  
  359.     if(hFirstStore == INVALID_HANDLE_VALUE)  
  360.     {  
  361.         printf("Not Find First Store!/n");  
  362.         return FALSE;  
  363.     }  
  364.       
  365.     // 添加第一个存储设备  
  366.     m_StoreArray.push_back(StoreInfo);  
  367.     wprintf(L"DeviceName:%s  StoreName:%s/n", StoreInfo.szDeviceName, StoreInfo.szStoreName);  
  368.   
  369.     // 查找下一个存储设备  
  370.     while (FindNextStore(hFirstStore, &StoreInfo) == TRUE)  
  371.     {  
  372.         m_StoreArray.push_back(StoreInfo);  
  373.         wprintf(L"DeviceName:%s  StoreName:%s/n", StoreInfo.szDeviceName, StoreInfo.szStoreName);  
  374.     }  
  375.   
  376.     // 关闭查找句柄  
  377.     FindCloseStore(hFirstStore);  
  378.     return TRUE;  
  379. }  
  380.   
  381. // 加载一个存储设备上所有的分区信息  
  382. BOOL CeStoreManager::LoadStorePartition(LPCTSTR storeDeviceName, CPartInfoArray &storePartArray)  
  383. {  
  384.     // 清除上次数据  
  385.     storePartArray.clear();  
  386.   
  387.     // 打开存储设备  
  388.     HANDLE hStore = OpenStore(storeDeviceName);  
  389.     if (hStore == INVALID_HANDLE_VALUE)  
  390.     {  
  391.         wprintf(L"Open Store %s Error!/n", storeDeviceName);  
  392.         return FALSE;  
  393.     }  
  394.   
  395.     // 查找第一个分区  
  396.     PARTINFO ptInfo = {0};  
  397.     ptInfo.cbSize = sizeof(ptInfo);  
  398.     HANDLE hFirstPart = FindFirstPartition(hStore, &ptInfo);  
  399.     CloseHandle(hStore);  
  400.     if (hFirstPart == INVALID_HANDLE_VALUE)  
  401.     {  
  402.         printf("Not Find First Partition!/n");  
  403.         return FALSE;  
  404.     }  
  405.   
  406.     // 添加第一个分区  
  407.     storePartArray.push_back(ptInfo);  
  408.     wprintf(L"PartName:%s  FileSys:%s VolumeName:%s/n", ptInfo.szPartitionName, ptInfo.szFileSys, ptInfo.szVolumeName);  
  409.   
  410.     // 查找其他分区  
  411.     while (FindNextPartition(hFirstPart, &ptInfo) == TRUE)  
  412.     {  
  413.         storePartArray.push_back(ptInfo);  
  414.         wprintf(L"PartName:%s  FileSys:%s VolumeName:%s/n", ptInfo.szPartitionName, ptInfo.szFileSys, ptInfo.szVolumeName);  
  415.     }  
  416.   
  417.     // 关闭查找句柄  
  418.     FindClosePartition(hFirstPart);  
  419.   
  420.     // 加载成功  
  421.     return TRUE;  
  422. }  
  423.   
  424. // 获得安全的动态库实例  
  425. BOOL CeStoreManager::GetSafeDllInstance()  
  426. {  
  427.     if (m_hUtilDll != NULL)  
  428.     {  
  429.         return TRUE;  
  430.     }  
  431.   
  432.     // 加载动态库  
  433.     m_hUtilDll = LoadLibrary(L"fatutil.dll");     
  434.     if (m_hUtilDll != NULL)  
  435.     {  
  436.         return TRUE;  
  437.     }  
  438.   
  439.     return FALSE;  
  440. }  
  441.   
  442. // 释放动态库  
  443. void CeStoreManager::FreeDllInstance()  
  444. {  
  445.     if (m_hUtilDll != NULL)  
  446.     {  
  447.         FreeLibrary(m_hUtilDll);  
  448.     }  
  449. }  
  450.   
  451. // 获得安全存储设备索引  
  452. BOOL CeStoreManager::GetSafeIndex(long storeIndex)  
  453. {  
  454.     if (storeIndex<0 || storeIndex>=(long)m_StoreArray.size())  
  455.     {  
  456.         return FALSE;  
  457.     }  
  458.   
  459.     return TRUE;  
  460. }  
  461.   
  462. BOOL CeStoreManager::GetSafeIndex(long storeIndex, long partIndex)  
  463. {  
  464.     if (storeIndex<0 || storeIndex>=(long)m_PartArray.size())  
  465.     {  
  466.         return FALSE;  
  467.     }  
  468.   
  469.     if (partIndex<0 || partIndex>=(long)m_PartArray[storeIndex].size())  
  470.     {  
  471.         return FALSE;  
  472.     }  
  473.   
  474.     return TRUE;  
  475. }  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值