Impl get tables with sql
This commit is contained in:
parent
1f5eae96de
commit
a49339a2a0
17
App/App.cpp
17
App/App.cpp
@ -13,7 +13,7 @@
|
||||
void printContacts(ContactMap_t contacts)
|
||||
{
|
||||
wprintf(L"contacts number: %ld\n", contacts.size());
|
||||
for (auto it = contacts.begin(); it != contacts.end(); ++it) {
|
||||
for (auto it = contacts.begin(); it != contacts.end(); it++) {
|
||||
wprintf(L"%s\t%s\t%s\t%s\t%s\t%s\t%s\r\n", it->second.wxId.c_str(), it->second.wxCode.c_str(),
|
||||
it->second.wxName.c_str(), it->second.wxGender.c_str(), it->second.wxCountry.c_str(),
|
||||
it->second.wxProvince.c_str(), it->second.wxCity.c_str());
|
||||
@ -23,11 +23,19 @@ void printContacts(ContactMap_t contacts)
|
||||
void printDbNames(vector<wstring> vDbs)
|
||||
{
|
||||
wprintf(L"db numbers: %ld\n", vDbs.size());
|
||||
for (auto it = vDbs.begin(); it != vDbs.end(); ++it) {
|
||||
for (auto it = vDbs.begin(); it != vDbs.end(); it++) {
|
||||
wprintf(L"%s\n", (*it).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void printDbTables(DbTableVector_t tables)
|
||||
{
|
||||
wprintf(L"table numbers: %ld\n", tables.size());
|
||||
for (auto it = tables.begin(); it != tables.end(); it++) {
|
||||
wprintf(L"%s\n%s\n\n", (it->table).c_str(), (it->sql).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int onTextMsg(WxMessage_t msg)
|
||||
{
|
||||
wprintf(L"%s msgType: %d, msgSource: %d, isSelf: %d\n", msg.id.c_str(), msg.type, msg.source, msg.self);
|
||||
@ -84,6 +92,11 @@ int main()
|
||||
// 测试获取数据库名
|
||||
auto vDbNames = WxGetDbNames();
|
||||
printDbNames(vDbNames);
|
||||
Sleep(1000); // 等待1秒
|
||||
|
||||
// 测试获取数据库中的表
|
||||
auto vDbTables = WxGetDbTables(L"ChatMsg.db");
|
||||
printDbTables(vDbTables);
|
||||
|
||||
while (1) {
|
||||
Sleep(10000); // 休眠,释放CPU
|
||||
|
@ -39,6 +39,13 @@ interface ISpy
|
||||
typedef RpcContact_t *PRpcContact;
|
||||
typedef RpcContact_t **PPRpcContact;
|
||||
|
||||
typedef struct RpcTables {
|
||||
BSTR table; // 表名
|
||||
BSTR sql; // 建表 SQL
|
||||
} RpcTables_t;
|
||||
typedef RpcTables_t *PRpcTables;
|
||||
typedef RpcTables_t **PPRpcTables;
|
||||
|
||||
int IsLogin();
|
||||
int SendTextMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *at_wxid,
|
||||
[ in, string ] const wchar_t *msg);
|
||||
@ -46,6 +53,7 @@ interface ISpy
|
||||
int GetMsgTypes([out] int *pNum, [ out, size_is(, *pNum) ] PPRpcIntBstrPair *msgTypes);
|
||||
int GetContacts([out] int *pNum, [ out, size_is(, *pNum) ] PPRpcContact *contacts);
|
||||
int GetDbNames([out] int *pNum, [ out, size_is(, *pNum) ] BSTR **dbs);
|
||||
int GetDbTables([ in, string ] const wchar_t *db, [out] int *pNum, [ out, size_is(, *pNum) ] PPRpcTables *tbls);
|
||||
|
||||
void EnableReceiveMsg();
|
||||
[callback] int ReceiveMsg([in] RpcMessage_t rpcMsg);
|
||||
|
@ -174,6 +174,27 @@ BSTR *RpcGetDbNames(int *pNum)
|
||||
return pBstr;
|
||||
}
|
||||
|
||||
PPRpcTables RpcGetDbTables(const wchar_t *db, int *pNum)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long ulCode = 0;
|
||||
PPRpcTables ppRpcTables = NULL;
|
||||
|
||||
RpcTryExcept { ret = client_GetDbTables(db, pNum, &ppRpcTables); }
|
||||
RpcExcept(1)
|
||||
{
|
||||
ulCode = RpcExceptionCode();
|
||||
printf("RpcGetDbTables exception 0x%lx = %ld\n", ulCode, ulCode);
|
||||
}
|
||||
RpcEndExcept;
|
||||
if (ret != 0) {
|
||||
printf("RpcGetDbTables Failed: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ppRpcTables;
|
||||
}
|
||||
|
||||
int server_ReceiveMsg(RpcMessage_t rpcMsg)
|
||||
{
|
||||
WxMessage_t msg;
|
||||
|
@ -12,3 +12,4 @@ int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path);
|
||||
PPRpcIntBstrPair RpcGetMsgTypes(int *pNum);
|
||||
PPRpcContact RpcGetContacts(int *pNum);
|
||||
BSTR *RpcGetDbNames(int *pNum);
|
||||
PPRpcTables RpcGetDbTables(const wchar_t *db, int *pNum);
|
||||
|
21
SDK/sdk.cpp
21
SDK/sdk.cpp
@ -187,3 +187,24 @@ std::vector<std::wstring> WxGetDbNames()
|
||||
|
||||
return vDbs;
|
||||
}
|
||||
|
||||
DbTableVector_t WxGetDbTables(wstring db)
|
||||
{
|
||||
DbTableVector_t vTables;
|
||||
int size = 0;
|
||||
PPRpcTables pp = RpcGetDbTables(db.c_str(), &size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
WxDbTable_t tbl;
|
||||
tbl.table = GetWstringFromBstr(pp[i]->table);
|
||||
tbl.sql = GetWstringFromBstr(pp[i]->sql);
|
||||
|
||||
vTables.push_back(tbl);
|
||||
midl_user_free(pp[i]);
|
||||
}
|
||||
|
||||
if (pp) {
|
||||
midl_user_free(pp);
|
||||
}
|
||||
|
||||
return vTables;
|
||||
}
|
||||
|
@ -5,4 +5,5 @@
|
||||
WxGetMsgTypes
|
||||
WxSendImageMsg
|
||||
WxGetContacts
|
||||
WxGetDbNames
|
||||
WxGetDbNames
|
||||
WxGetDbTables
|
||||
|
@ -28,8 +28,14 @@ typedef struct WxContact {
|
||||
wstring wxGender; // 性别
|
||||
} WxContact_t;
|
||||
|
||||
typedef struct WxDbTable {
|
||||
wstring table; // 表名
|
||||
wstring sql; // 建表 SQL
|
||||
} WxDbTable_t;
|
||||
|
||||
typedef map<int, wstring> MsgTypesMap_t;
|
||||
typedef map<wstring, WxContact_t> ContactMap_t;
|
||||
typedef vector<WxDbTable_t> DbTableVector_t;
|
||||
|
||||
int WxInitSDK();
|
||||
int WxSetTextMsgCb(const std::function<int(WxMessage_t)> &onMsg);
|
||||
@ -38,3 +44,4 @@ int WxSendImageMsg(wstring wxid, wstring path);
|
||||
ContactMap_t WxGetContacts();
|
||||
MsgTypesMap_t WxGetMsgTypes();
|
||||
vector<wstring> WxGetDbNames();
|
||||
DbTableVector_t WxGetDbTables(wstring db);
|
||||
|
@ -187,6 +187,15 @@ wstring GetWstringFromBstr(BSTR p)
|
||||
return ws;
|
||||
}
|
||||
|
||||
BSTR GetBstrFromString(const char *str)
|
||||
{
|
||||
int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0);
|
||||
BSTR bstr = SysAllocStringLen(0, wslen);
|
||||
MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
|
||||
|
||||
return bstr;
|
||||
}
|
||||
|
||||
BSTR GetBstrFromWstring(wstring ws)
|
||||
{
|
||||
if (!ws.empty()) {
|
||||
|
@ -24,5 +24,6 @@ BSTR GetBstrByAddress(DWORD address);
|
||||
void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg);
|
||||
DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address);
|
||||
std::wstring GetWstringFromBstr(BSTR p);
|
||||
BSTR GetBstrFromString(const char *str);
|
||||
BSTR GetBstrFromWstring(std::wstring ws);
|
||||
std::wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "exec_sql.h"
|
||||
#include "load_calls.h"
|
||||
#include "util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -12,6 +13,32 @@ extern DWORD g_WeChatWinDllAddr;
|
||||
typedef map<wstring, DWORD> dbMap_t;
|
||||
static dbMap_t dbMap;
|
||||
|
||||
// 回调函数指针
|
||||
typedef int (*sqlite3_callback)(void *, int, char **, char **);
|
||||
|
||||
// sqlite3_exec函数指针
|
||||
typedef int(__cdecl *Sqlite3_exec)(DWORD, /* The database on which the SQL executes */
|
||||
const char *, /* The SQL to be executed */
|
||||
sqlite3_callback, /* Invoke this callback routine */
|
||||
void *, /* First argument to xCallback() */
|
||||
char ** /* Write error messages here */
|
||||
);
|
||||
|
||||
static int cbGetTables(void *ret, int argc, char **argv, char **azColName)
|
||||
{
|
||||
vector<RpcTables_t> *p = (vector<RpcTables_t> *)ret;
|
||||
RpcTables_t tbl = { 0 };
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (strcmp(azColName[i], "name") == 0) {
|
||||
tbl.table = argv[i] ? GetBstrFromString(argv[i]) : NULL;
|
||||
} else if (strcmp(azColName[i], "sql") == 0) {
|
||||
tbl.sql = argv[i] ? GetBstrFromString(argv[i]) : NULL;
|
||||
}
|
||||
}
|
||||
p->push_back(tbl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
vector<wstring> GetDbNames()
|
||||
{
|
||||
vector<wstring> vDbs;
|
||||
@ -31,3 +58,17 @@ vector<wstring> GetDbNames()
|
||||
}
|
||||
return vDbs;
|
||||
}
|
||||
|
||||
vector<RpcTables_t> GetDbTables(wstring db)
|
||||
{
|
||||
vector<RpcTables_t> vTables;
|
||||
const char *sql = "select * from sqlite_master where type=\"table\";";
|
||||
Sqlite3_exec p_Sqlite3_exec = (Sqlite3_exec)(g_WeChatWinDllAddr + g_WxCalls.sql.exec);
|
||||
|
||||
auto it = dbMap.find(db);
|
||||
if (it != dbMap.end()) {
|
||||
p_Sqlite3_exec(it->second, sql, (sqlite3_callback)cbGetTables, &vTables, 0);
|
||||
}
|
||||
|
||||
return vTables;
|
||||
}
|
||||
|
@ -6,3 +6,4 @@
|
||||
#include "rpc_h.h"
|
||||
|
||||
std::vector<std::wstring> GetDbNames();
|
||||
std::vector<RpcTables_t> GetDbTables(std::wstring db);
|
||||
|
@ -139,6 +139,29 @@ int server_GetDbNames(int *pNum, BSTR **dbs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int server_GetDbTables(const wchar_t *db, int *pNum, PPRpcTables *tbls)
|
||||
{
|
||||
vector<RpcTables_t> tables = GetDbTables(db);
|
||||
*pNum = tables.size();
|
||||
PPRpcTables pp = (PPRpcTables)midl_user_allocate(*pNum * sizeof(RpcTables_t));
|
||||
if (pp == NULL) {
|
||||
printf("server_GetMsgTypes midl_user_allocate Failed for pp\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (auto it = tables.begin(); it != tables.end(); it++) {
|
||||
PRpcTables p = (PRpcTables)midl_user_allocate(sizeof(RpcTables_t));
|
||||
p->table = it->table;
|
||||
p->sql = it->sql;
|
||||
pp[index++] = p;
|
||||
}
|
||||
|
||||
*tbls = pp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void * /*pBindingHandle*/)
|
||||
{
|
||||
return RPC_S_OK; // Always allow anyone.
|
||||
|
Loading…
Reference in New Issue
Block a user