提交 f6d75778 编写于 作者: L ljc545w

解决内存泄漏问题

上级 6c63780c
...@@ -58,17 +58,17 @@ void ClearResultArray() ...@@ -58,17 +58,17 @@ void ClearResultArray()
SQLResultStruct *sr = (SQLResultStruct *)&SQLResult[i][j]; SQLResultStruct *sr = (SQLResultStruct *)&SQLResult[i][j];
if (sr->ColName) if (sr->ColName)
{ {
delete sr->ColName; delete[] sr->ColName;
sr->ColName = NULL; sr->ColName = NULL;
} }
if (sr->content) if (sr->content)
{ {
delete sr->content; delete[] sr->content;
sr->content = NULL; sr->content = NULL;
} }
if (sr->BlobContent) if (sr->BlobContent)
{ {
delete sr->BlobContent; delete[] sr->BlobContent;
sr->BlobContent = NULL; sr->BlobContent = NULL;
} }
} }
...@@ -93,29 +93,30 @@ SAFEARRAY *CreateSQLResultSafeArray() ...@@ -93,29 +93,30 @@ SAFEARRAY *CreateSQLResultSafeArray()
SQLResultStruct *ptrResult = (SQLResultStruct *)&SQLResult[i][j]; SQLResultStruct *ptrResult = (SQLResultStruct *)&SQLResult[i][j];
if (i == 0) if (i == 0)
{ {
ATL::CComVariant val(ptrResult->ColName);
Index[0] = 0; Index[0] = 0;
Index[1] = j; Index[1] = j;
hr = SafeArrayPutElement(psaValue, Index, &(_variant_t)ptrResult->ColName); hr = SafeArrayPutElement(psaValue, Index, &val);
} }
Index[0] = i + 1; Index[0] = i + 1;
Index[1] = j; Index[1] = j;
if (ptrResult->content) if (ptrResult->content)
hr = SafeArrayPutElement(psaValue, Index, &(_variant_t)ptrResult->content); {
ATL::CComVariant val(ptrResult->content);
hr = SafeArrayPutElement(psaValue, Index, &val);
}
else else
{ {
VARIANT varChunk;
SAFEARRAY *bsa;
BYTE *pByte = NULL; BYTE *pByte = NULL;
SAFEARRAYBOUND rgsabound[1]; SAFEARRAYBOUND rgsabound[1];
rgsabound[0].cElements = ptrResult->BlobLength; rgsabound[0].cElements = ptrResult->BlobLength;
rgsabound[0].lLbound = 0; rgsabound[0].lLbound = 0;
bsa = SafeArrayCreate(VT_UI1, 1, rgsabound); ATL::CComSafeArray<BYTE> bsa(rgsabound);
SafeArrayAccessData(bsa, (void **)&pByte); SafeArrayAccessData(bsa.m_psa, (void **)&pByte);
memcpy(pByte, ptrResult->BlobContent, ptrResult->BlobLength); memcpy(pByte, ptrResult->BlobContent, ptrResult->BlobLength);
SafeArrayUnaccessData(bsa); SafeArrayUnaccessData(bsa.m_psa);
varChunk.vt = VT_ARRAY | VT_UI1; ATL::CComVariant val(bsa.m_psa);
varChunk.parray = bsa; hr = SafeArrayPutElement(psaValue, Index, &val);
hr = SafeArrayPutElement(psaValue, Index, &(_variant_t)varChunk);
} }
} }
} }
...@@ -140,7 +141,7 @@ VOID ReadSQLResultFromWeChatProcess(HANDLE hProcess, DWORD dwHandle) ...@@ -140,7 +141,7 @@ VOID ReadSQLResultFromWeChatProcess(HANDLE hProcess, DWORD dwHandle)
char *ColName = new char[sqlresultAddr.l_ColName + 1]; char *ColName = new char[sqlresultAddr.l_ColName + 1];
sqlresult.ColName = new wchar_t[sqlresultAddr.l_ColName + 1]; sqlresult.ColName = new wchar_t[sqlresultAddr.l_ColName + 1];
ReadProcessMemory(hProcess, (LPCVOID)sqlresultAddr.ColName, ColName, sqlresultAddr.l_ColName + 1, 0); ReadProcessMemory(hProcess, (LPCVOID)sqlresultAddr.ColName, ColName, sqlresultAddr.l_ColName + 1, 0);
MultiByteToWideChar(CP_ACP, 0, ColName, -1, sqlresult.ColName, strlen(ColName) + 1); MultiByteToWideChar(CP_UTF8, 0, ColName, -1, sqlresult.ColName, strlen(ColName) + 1);
char *content = new char[sqlresultAddr.l_content + 1]; char *content = new char[sqlresultAddr.l_content + 1];
if (!sqlresultAddr.isblob) if (!sqlresultAddr.isblob)
{ {
......
#pragma once #pragma once
#include<windows.h> #include <windows.h>
SAFEARRAY* ExecuteSQL(DWORD pid,DWORD DbHandle, BSTR sql); SAFEARRAY *ExecuteSQL(DWORD pid, DWORD DbHandle, BSTR sql);
\ No newline at end of file
...@@ -31,16 +31,16 @@ struct DbInfoAddrStruct ...@@ -31,16 +31,16 @@ struct DbInfoAddrStruct
struct TableInfoStruct struct TableInfoStruct
{ {
char *name; std::string name;
char *tbl_name; std::string tbl_name;
char *sql; std::string sql;
char *rootpage; std::string rootpage;
}; };
struct DbInfoStruct struct DbInfoStruct
{ {
DWORD handle; DWORD handle;
wchar_t *dbname; std::wstring dbname;
vector<TableInfoStruct> tables; vector<TableInfoStruct> tables;
DWORD count; DWORD count;
}; };
...@@ -69,7 +69,7 @@ SAFEARRAY *CreateDbInfoSafeArray() ...@@ -69,7 +69,7 @@ SAFEARRAY *CreateDbInfoSafeArray()
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"dbname"); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"dbname");
ArrayIndex[1] = 0; ArrayIndex[1] = 0;
ArrayIndex[2] = {1}; ArrayIndex[2] = {1};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].dbname); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].dbname.c_str());
ArrayIndex[1] = 1; ArrayIndex[1] = 1;
ArrayIndex[2] = {0}; ArrayIndex[2] = {0};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"Handle"); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"Handle");
...@@ -81,25 +81,25 @@ SAFEARRAY *CreateDbInfoSafeArray() ...@@ -81,25 +81,25 @@ SAFEARRAY *CreateDbInfoSafeArray()
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"name"); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"name");
ArrayIndex[1] = 2; ArrayIndex[1] = 2;
ArrayIndex[2] = {1}; ArrayIndex[2] = {1};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].name); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].name.c_str());
ArrayIndex[1] = 3; ArrayIndex[1] = 3;
ArrayIndex[2] = {0}; ArrayIndex[2] = {0};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"tbl_name"); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"tbl_name");
ArrayIndex[1] = 3; ArrayIndex[1] = 3;
ArrayIndex[2] = {1}; ArrayIndex[2] = {1};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].tbl_name); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].tbl_name.c_str());
ArrayIndex[1] = 4; ArrayIndex[1] = 4;
ArrayIndex[2] = {0}; ArrayIndex[2] = {0};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"rootpage"); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"rootpage");
ArrayIndex[1] = 4; ArrayIndex[1] = 4;
ArrayIndex[2] = {1}; ArrayIndex[2] = {1};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].rootpage); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].rootpage.c_str());
ArrayIndex[1] = 5; ArrayIndex[1] = 5;
ArrayIndex[2] = {0}; ArrayIndex[2] = {0};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"sql"); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)L"sql");
ArrayIndex[1] = 5; ArrayIndex[1] = 5;
ArrayIndex[2] = {1}; ArrayIndex[2] = {1};
hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].sql); hr = SafeArrayPutElement(psaValue, ArrayIndex, &(_variant_t)dbs[i].tables[j].sql.c_str());
index++; index++;
} }
} }
...@@ -125,22 +125,33 @@ SAFEARRAY *GetDbHandles(DWORD pid) ...@@ -125,22 +125,33 @@ SAFEARRAY *GetDbHandles(DWORD pid)
DbInfoStruct db = {0}; DbInfoStruct db = {0};
db.handle = dbaddr.handle; db.handle = dbaddr.handle;
db.count = dbaddr.count; db.count = dbaddr.count;
db.dbname = new wchar_t[dbaddr.l_dbname + 1]; wchar_t *wbuf = new wchar_t[dbaddr.l_dbname + 1];
ReadProcessMemory(hp.GetHandle(), (LPCVOID)dbaddr.dbname, db.dbname, sizeof(wchar_t) * (dbaddr.l_dbname + 1), 0); ReadProcessMemory(hp.GetHandle(), (LPCVOID)dbaddr.dbname, wbuf, sizeof(wchar_t) * (dbaddr.l_dbname + 1), 0);
db.dbname = std::wstring(wbuf);
delete[] wbuf;
DWORD db_table_start_addr = dbaddr.v_data; DWORD db_table_start_addr = dbaddr.v_data;
while (db_table_start_addr < dbaddr.v_end1) while (db_table_start_addr < dbaddr.v_end1)
{ {
char *buf = NULL;
TableInfoAddrStruct tbaddr = {0}; TableInfoAddrStruct tbaddr = {0};
TableInfoStruct tb = {0}; TableInfoStruct tb;
ReadProcessMemory(hp.GetHandle(), (LPCVOID)db_table_start_addr, &tbaddr, sizeof(TableInfoAddrStruct), 0); ReadProcessMemory(hp.GetHandle(), (LPCVOID)db_table_start_addr, &tbaddr, sizeof(TableInfoAddrStruct), 0);
tb.name = new char[tbaddr.l_name + 1]; buf = new char[tbaddr.l_name + 1];
ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.name, tb.name, tbaddr.l_name + 1, 0); ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.name, buf, tbaddr.l_name + 1, 0);
tb.tbl_name = new char[tbaddr.l_tbl_name + 1]; tb.name = std::string(buf);
ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.tbl_name, tb.tbl_name, tbaddr.l_tbl_name + 1, 0); delete[] buf;
tb.rootpage = new char[tbaddr.l_rootpage + 1]; buf = new char[tbaddr.l_tbl_name + 1];
ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.rootpage, tb.rootpage, tbaddr.l_rootpage + 1, 0); ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.tbl_name, buf, tbaddr.l_tbl_name + 1, 0);
tb.sql = new char[tbaddr.l_sql + 1]; tb.tbl_name = std::string(buf);
ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.sql, tb.sql, tbaddr.l_sql + 1, 0); delete[] buf;
buf = new char[tbaddr.l_rootpage + 1];
ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.rootpage, buf, tbaddr.l_rootpage + 1, 0);
tb.rootpage = std::string(buf);
delete[] buf;
buf = new char[tbaddr.l_sql + 1];
ReadProcessMemory(hp.GetHandle(), (LPCVOID)tbaddr.sql, buf, tbaddr.l_sql + 1, 0);
tb.sql = std::string(buf);
delete[] buf;
db.tables.push_back(tb); db.tables.push_back(tb);
db_table_start_addr += sizeof(TableInfoAddrStruct); db_table_start_addr += sizeof(TableInfoAddrStruct);
} }
......
#include "pch.h" #include "pch.h"
VARIANT GetQrcodeImage(DWORD pid) ATL::CComVariant GetQrcodeImage(DWORD pid)
{ {
VARIANT vsa;
vsa.vt = VT_ARRAY | VT_UI1;
V_ARRAY(&vsa) = NULL;
WeChatProcess hp(pid); WeChatProcess hp(pid);
if (!hp.m_init) if (!hp.m_init)
return vsa; return NULL;
DWORD GetQrcodeImageAddr = hp.GetProcAddr(GetQrcodeImageRemote); DWORD GetQrcodeImageAddr = hp.GetProcAddr(GetQrcodeImageRemote);
DWORD ret = CallRemoteFunction(hp.GetHandle(), GetQrcodeImageAddr, NULL); DWORD ret = CallRemoteFunction(hp.GetHandle(), GetQrcodeImageAddr, NULL);
if (ret == 0) if (ret == 0)
return vsa; return NULL;
DWORD ret_info[2] = {0}; DWORD ret_info[2] = {0};
ReadProcessMemory(hp.GetHandle(), (LPCVOID)ret, &ret_info, sizeof(ret_info), 0); ReadProcessMemory(hp.GetHandle(), (LPCVOID)ret, &ret_info, sizeof(ret_info), 0);
DWORD buf_addr = ret_info[0]; DWORD buf_addr = ret_info[0];
int size = ret_info[1]; int size = ret_info[1];
if (size == 0 || buf_addr == 0) if (size == 0 || buf_addr == 0)
return vsa; return NULL;
unique_ptr<BYTE[]> image(new BYTE[size + 1]()); unique_ptr<BYTE[]> image(new BYTE[size + 1]());
ReadProcessMemory(hp.GetHandle(), (LPCVOID)buf_addr, image.get(), size, 0); ReadProcessMemory(hp.GetHandle(), (LPCVOID)buf_addr, image.get(), size, 0);
SAFEARRAYBOUND rgsaBound = {(ULONG)size, 0}; SAFEARRAYBOUND rgsaBound = {(ULONG)size, 0};
SAFEARRAY *psaValue = SafeArrayCreate(VT_UI1, 1, &rgsaBound); ATL::CComSafeArray<BYTE> cpsa(rgsaBound);
BYTE *buf = NULL; BYTE *buf = NULL;
::SafeArrayAccessData(psaValue, (void **)&buf); ::SafeArrayAccessData(cpsa.m_psa, (void **)&buf);
memcpy(buf, image.get(), size); memcpy(buf, image.get(), size);
::SafeArrayUnaccessData(psaValue); ::SafeArrayUnaccessData(cpsa.m_psa);
V_ARRAY(&vsa) = psaValue; ATL::CComVariant cva(cpsa.m_psa);
return vsa; cpsa.Destroy();
return cva;
} }
BOOL isWxLogin(DWORD pid) BOOL isWxLogin(DWORD pid)
......
#pragma once #pragma once
#include <windows.h> #include <windows.h>
VARIANT GetQrcodeImage(DWORD pid); #include <atlcomcli.h>
#include <atlsafe.h>
ATL::CComVariant GetQrcodeImage(DWORD pid);
BOOL isWxLogin(DWORD pid); BOOL isWxLogin(DWORD pid);
...@@ -116,10 +116,13 @@ STDMETHODIMP CWeChatRobot::CSendCard(DWORD pid, BSTR receiver, BSTR sharedwxid, ...@@ -116,10 +116,13 @@ STDMETHODIMP CWeChatRobot::CSendCard(DWORD pid, BSTR receiver, BSTR sharedwxid,
*/ */
STDMETHODIMP CWeChatRobot::CGetFriendList(DWORD pid, VARIANT *__result) STDMETHODIMP CWeChatRobot::CGetFriendList(DWORD pid, VARIANT *__result)
{ {
VARIANT vsaValue; VariantInit(__result);
vsaValue.vt = VT_ARRAY | VT_VARIANT; SAFEARRAY *psaValue = GetFriendList(pid);
V_ARRAY(&vsaValue) = GetFriendList(pid); ATL::CComSafeArray<VARIANT> cpsa;
*__result = vsaValue; cpsa.Attach(psaValue);
ATL::CComVariant cva = cpsa.m_psa;
cva.Detach(__result);
cpsa.Destroy();
return S_OK; return S_OK;
} }
...@@ -207,10 +210,13 @@ STDMETHODIMP CWeChatRobot::CStopReceiveMessage(DWORD pid, int *__result) ...@@ -207,10 +210,13 @@ STDMETHODIMP CWeChatRobot::CStopReceiveMessage(DWORD pid, int *__result)
*/ */
STDMETHODIMP CWeChatRobot::CGetChatRoomMembers(DWORD pid, BSTR chatroomid, VARIANT *__result) STDMETHODIMP CWeChatRobot::CGetChatRoomMembers(DWORD pid, BSTR chatroomid, VARIANT *__result)
{ {
VARIANT vsaValue; VariantInit(__result);
vsaValue.vt = VT_ARRAY | VT_VARIANT; SAFEARRAY *psaValue = GetChatRoomMembers(pid, chatroomid);
V_ARRAY(&vsaValue) = GetChatRoomMembers(pid, chatroomid); ATL::CComSafeArray<VARIANT> cpsa;
*__result = vsaValue; cpsa.Attach(psaValue);
ATL::CComVariant cva = cpsa.m_psa;
cva.Detach(__result);
cpsa.Destroy();
return S_OK; return S_OK;
} }
...@@ -220,10 +226,13 @@ STDMETHODIMP CWeChatRobot::CGetChatRoomMembers(DWORD pid, BSTR chatroomid, VARIA ...@@ -220,10 +226,13 @@ STDMETHODIMP CWeChatRobot::CGetChatRoomMembers(DWORD pid, BSTR chatroomid, VARIA
*/ */
STDMETHODIMP CWeChatRobot::CGetDbHandles(DWORD pid, VARIANT *__result) STDMETHODIMP CWeChatRobot::CGetDbHandles(DWORD pid, VARIANT *__result)
{ {
VARIANT vsaValue; VariantInit(__result);
vsaValue.vt = VT_ARRAY | VT_VARIANT; SAFEARRAY *psaValue = GetDbHandles(pid);
V_ARRAY(&vsaValue) = GetDbHandles(pid); ATL::CComSafeArray<VARIANT> cpsa;
*__result = vsaValue; cpsa.Attach(psaValue);
ATL::CComVariant cva = cpsa.m_psa;
cva.Detach(__result);
cpsa.Destroy();
return S_OK; return S_OK;
} }
...@@ -235,10 +244,13 @@ STDMETHODIMP CWeChatRobot::CGetDbHandles(DWORD pid, VARIANT *__result) ...@@ -235,10 +244,13 @@ STDMETHODIMP CWeChatRobot::CGetDbHandles(DWORD pid, VARIANT *__result)
*/ */
STDMETHODIMP CWeChatRobot::CExecuteSQL(DWORD pid, DWORD DbHandle, BSTR sql, VARIANT *__result) STDMETHODIMP CWeChatRobot::CExecuteSQL(DWORD pid, DWORD DbHandle, BSTR sql, VARIANT *__result)
{ {
VARIANT vsaValue; VariantInit(__result);
vsaValue.vt = VT_ARRAY | VT_VARIANT; SAFEARRAY *psaValue = ExecuteSQL(pid, DbHandle, sql);
V_ARRAY(&vsaValue) = ExecuteSQL(pid, DbHandle, sql); ATL::CComSafeArray<VARIANT> cpsa;
*__result = vsaValue; cpsa.Attach(psaValue);
ATL::CComVariant cva = cpsa.m_psa;
cva.Detach(__result);
cpsa.Destroy();
return S_OK; return S_OK;
} }
...@@ -318,10 +330,13 @@ STDMETHODIMP CWeChatRobot::CStartWeChat(int *__result) ...@@ -318,10 +330,13 @@ STDMETHODIMP CWeChatRobot::CStartWeChat(int *__result)
*/ */
STDMETHODIMP CWeChatRobot::CSearchContactByNet(DWORD pid, BSTR keyword, VARIANT *__result) STDMETHODIMP CWeChatRobot::CSearchContactByNet(DWORD pid, BSTR keyword, VARIANT *__result)
{ {
VARIANT vsaValue; VariantInit(__result);
vsaValue.vt = VT_ARRAY | VT_VARIANT; SAFEARRAY *psaValue = SearchContactByNet(pid, keyword);
V_ARRAY(&vsaValue) = SearchContactByNet(pid, keyword); ATL::CComSafeArray<VARIANT> cpsa;
*__result = vsaValue; cpsa.Attach(psaValue);
ATL::CComVariant cva = cpsa.m_psa;
cva.Detach(__result);
cpsa.Destroy();
return S_OK; return S_OK;
} }
...@@ -545,16 +560,15 @@ STDMETHODIMP CWeChatRobot::COpenBrowser(DWORD pid, BSTR url, int *__result) ...@@ -545,16 +560,15 @@ STDMETHODIMP CWeChatRobot::COpenBrowser(DWORD pid, BSTR url, int *__result)
STDMETHODIMP CWeChatRobot::CGetHistoryPublicMsg(DWORD pid, BSTR PublicId, BSTR Offset, VARIANT *__result) STDMETHODIMP CWeChatRobot::CGetHistoryPublicMsg(DWORD pid, BSTR PublicId, BSTR Offset, VARIANT *__result)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
VariantInit(__result);
wstring result = GetHistoryPublicMsg(pid, PublicId, Offset); wstring result = GetHistoryPublicMsg(pid, PublicId, Offset);
VARIANT vsaValue;
vsaValue.vt = VT_ARRAY | VT_VARIANT;
SAFEARRAYBOUND rgsaBound = {1, 0}; SAFEARRAYBOUND rgsaBound = {1, 0};
SAFEARRAY *psaValue = SafeArrayCreate(VT_VARIANT, 1, &rgsaBound); ATL::CComSafeArray<VARIANT> cpsa(rgsaBound);
long index = 0; long index = 0;
// 数据大小超过16382个字符,客户端调用可能出现异常,因此将数据放入安全数组中传递 // 数据大小超过16382个字符,客户端调用可能出现异常,因此将数据放入安全数组中传递
hr = SafeArrayPutElement(psaValue, &index, &(_variant_t)result.c_str()); hr = SafeArrayPutElement(cpsa.m_psa, &index, &(_variant_t)result.c_str());
V_ARRAY(&vsaValue) = psaValue; ATL::CComVariant vsa(cpsa.m_psa);
*__result = vsaValue; vsa.Detach(__result);
return S_OK; return S_OK;
} }
...@@ -576,7 +590,9 @@ STDMETHODIMP CWeChatRobot::CForwardMessage(DWORD pid, BSTR wxid, ULONG64 msgid, ...@@ -576,7 +590,9 @@ STDMETHODIMP CWeChatRobot::CForwardMessage(DWORD pid, BSTR wxid, ULONG64 msgid,
*/ */
STDMETHODIMP CWeChatRobot::CGetQrcodeImage(DWORD pid, VARIANT *__result) STDMETHODIMP CWeChatRobot::CGetQrcodeImage(DWORD pid, VARIANT *__result)
{ {
*__result = GetQrcodeImage(pid); ATL::CComVariant cva = GetQrcodeImage(pid);
VariantInit(__result);
cva.Detach(__result);
return S_OK; return S_OK;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册