iauth: add enums, fix struct member names

This commit is contained in:
Hay1tsme 2023-02-12 03:12:22 -05:00
parent 47784820b7
commit baecb9efbb
2 changed files with 248 additions and 105 deletions

View File

@ -16,7 +16,7 @@ void iauth_set_config(struct amcus_config *cfg)
static ULONG REF_COUNT = 0; static ULONG REF_COUNT = 0;
static bool is_init = true; static bool is_init = true;
static int amauthd_state = 9; static int amauthd_state = DAEMON_DL;
static HRESULT STDMETHODCALLTYPE IAuth_QueryInterface(IAuth FAR *This, REFIID riid, void **ppvObj) static HRESULT STDMETHODCALLTYPE IAuth_QueryInterface(IAuth FAR *This, REFIID riid, void **ppvObj)
{ {
@ -31,7 +31,7 @@ static HRESULT STDMETHODCALLTYPE IAuth_QueryInterface(IAuth FAR *This, REFIID ri
*ppvObj = This; *ppvObj = This;
return S_OK; return S_OK;
} }
return E_NOINTERFACE; return E_NOINTERFACE;
} }
@ -54,7 +54,7 @@ static HRESULT STDMETHODCALLTYPE IAuth_Initialize(IAuth FAR *This, int64_t p0)
return 1; return 1;
} }
is_init = true; is_init = true;
amauthd_state = 5; amauthd_state = DAEMON_INIT;
return 0; return 0;
} }
@ -65,7 +65,7 @@ static HRESULT STDMETHODCALLTYPE IAuth_Finalize(IAuth FAR *This)
return 1; return 1;
} }
is_init = false; is_init = false;
amauthd_state = 0; amauthd_state = DAEMON_UNKNOWN;
return 0; return 0;
} }
@ -97,9 +97,9 @@ static HRESULT STDMETHODCALLTYPE IAuth_Func8(IAuth FAR *This)
} }
// Likely has to do with mucha and the updater // Likely has to do with mucha and the updater
static HRESULT STDMETHODCALLTYPE IAuth_GetUpdaterState(IAuth FAR *This, struct amcus_updater_state *arr) static HRESULT STDMETHODCALLTYPE IAuth_GetUpdaterState(IAuth FAR *This, struct amcus_state *arr)
{ {
// dprintf("IAuth: %s hit!\n", __func__); // dprintf("IAuth: %s hit!\n", __func__);
memset(arr, 0, sizeof(*arr)); memset(arr, 0, sizeof(*arr));
char cacfg_ver[6]; char cacfg_ver[6];
@ -113,42 +113,41 @@ static HRESULT STDMETHODCALLTYPE IAuth_GetUpdaterState(IAuth FAR *This, struct a
ver_btm %= (ver_top * 100); ver_btm %= (ver_top * 100);
} }
arr->Member0.Member0 = 15; arr->allnet_state.state = DAEMON_IDLE;
arr->Member0.Member8 = 2; arr->allnet_state.auth_state = 2;
arr->Member0.MemberC = 1; arr->allnet_state.auth_count = 1;
arr->Member18.Member0 = 9; arr->mucha_state.state = DAEMON_DL;
arr->Member18.Member8 = 2; arr->mucha_state.auth_state = 2;
arr->Member18.MemberC = 1; arr->mucha_state.auth_count = 1;
arr->Member18.Member10 = 27; arr->mucha_state.state_dlexec = DLEXEC_PROC;
arr->Member18.Member14 = 32; arr->mucha_state.state_dlstep = DLSTEP_IDLE;
arr->Member18.Member18 = 43; arr->mucha_state.state_dllan = DLLAN_DISABLE;
arr->Member18.Member1C = 52; arr->mucha_state.state_dlwan = DLWAN_COMPLETE;
arr->Member18.Member20 = 59; arr->mucha_state.state_io = DAEMON_IO_NONE;
arr->Member18.cacfg_ver_whole = ver_top; arr->mucha_state.cacfg_ver_major = ver_top;
arr->Member18.cacfg_ver_decimal = ver_btm; arr->mucha_state.cacfg_ver_minor = ver_btm;
arr->Member18.app_ver_whole = ver_top; arr->mucha_state.app_ver_major = ver_top;
arr->Member18.app_ver_decimal = ver_btm; arr->mucha_state.app_ver_minor = ver_btm;
arr->Member18.Member60 = 1; arr->mucha_state.dl_check_complete = 1;
arr->clock_status = 1; arr->clock_status = 1;
arr->network_mode = 1; arr->auth_type = AUTH_TYPE_ALLNET;
arr->cab_type = 3; arr->cab_mode = DAEMON_MODE_STANDALONE;
arr->amauth_init_state = amauthd_state; arr->state = amauthd_state;
arr->MemberC4 = 0;
switch (amauthd_state) { switch (amauthd_state) {
case 5: amauthd_state = 6; break; case DAEMON_INIT: amauthd_state = DAEMON_AUTH_START; break;
case 6: amauthd_state = 15; break; case DAEMON_AUTH_START: amauthd_state = DAEMON_IDLE; break;
case 15: amauthd_state = 9; break; case DAEMON_IDLE: amauthd_state = DAEMON_DL; break;
default: break; default: break;
} }
return S_OK; return S_OK;
} }
// Valid valnues for mode are STANDALONE, CLIENT, SERVER // Valid valnues for mode are STANDALONE, CLIENT, SERVER
static HRESULT STDMETHODCALLTYPE IAuth_GetCabinetConfig(IAuth FAR *This, struct amcus_cab_config *arr) static HRESULT STDMETHODCALLTYPE IAuth_GetCabinetConfig(IAuth FAR *This, struct amcus_network_state *arr)
{ {
// dprintf("IAuth: %s hit!\n", __func__); // dprintf("IAuth: %s hit!\n", __func__);
@ -160,20 +159,21 @@ static HRESULT STDMETHODCALLTYPE IAuth_GetCabinetConfig(IAuth FAR *This, struct
char dongle_serial[13]; char dongle_serial[13];
wcstombs_s(NULL, am_serial, sizeof(am_serial), config.am_serial, sizeof(config.am_serial)); wcstombs_s(NULL, am_serial, sizeof(am_serial), config.am_serial, sizeof(config.am_serial));
// TODO: read the serial off a real dongle if enabled is 0
wcstombs_s(NULL, dongle_serial, sizeof(dongle_serial), config.dongle.serial, sizeof(config.dongle.serial)); wcstombs_s(NULL, dongle_serial, sizeof(dongle_serial), config.dongle.serial, sizeof(config.dongle.serial));
strcpy_s(arr->mode, sizeof(arr->mode), "STANDALONE"); strcpy_s(arr->mode, sizeof(arr->mode), "STANDALONE");
strcpy_s(arr->pcbid, sizeof(arr->pcbid), am_serial); strcpy_s(arr->pcbid, sizeof(arr->pcbid), am_serial);
strcpy_s(arr->dongle_serial, sizeof(arr->dongle_serial), dongle_serial); strcpy_s(arr->dongle_serial, sizeof(arr->dongle_serial), dongle_serial);
strcpy_s(arr->shop_router_ip, sizeof(arr->shop_router_ip), "192.168.123.254");
strcpy_s(arr->auth_server_ip, sizeof(arr->auth_server_ip), "192.168.1.114"); // TODO: Load fake IP addresses from config
strcpy_s(arr->local_ip, sizeof(arr->local_ip), "192.168.123.11"); strcpy_s(arr->shop_router_ip, sizeof(arr->shop_router_ip), "192.168.123.254"); // router ip
strcpy_s(arr->subnet_mask, sizeof(arr->subnet_mask), "255.255.225.0"); strcpy_s(arr->auth_server_ip, sizeof(arr->auth_server_ip), "192.168.1.114"); // "default" in dnshook
strcpy_s(arr->gateway, sizeof(arr->gateway), "192.168.123.254"); strcpy_s(arr->local_ip, sizeof(arr->local_ip), "192.168.123.11"); // fake ip
strcpy_s(arr->primary_dns, sizeof(arr->primary_dns), "192.168.1.3"); strcpy_s(arr->subnet_mask, sizeof(arr->subnet_mask), "255.255.225.0"); // fake subnet
strcpy_s(arr->gateway, sizeof(arr->gateway), "192.168.123.254"); // router ip
strcpy_s(arr->primary_dns, sizeof(arr->primary_dns), "192.168.1.3"); // ??
arr->hop_count = 1; arr->hop_count = 1;
arr->line_type = 1; arr->line_type = TYPE_FFT;
return S_OK; return S_OK;
} }
@ -286,7 +286,7 @@ static HRESULT STDMETHODCALLTYPE IAuth_GetMuchaAuthResponse(IAuth FAR *This, str
if (!is_init) { if (!is_init) {
return E_ACCESSDENIED; return E_ACCESSDENIED;
} }
strcpy_s(arr->shop_name, sizeof(arr->shop_name), "Test Shop!"); strcpy_s(arr->shop_name, sizeof(arr->shop_name), "Test Shop!");
strcpy_s(arr->shop_name_en, sizeof(arr->shop_name_en), "Test Shop!"); strcpy_s(arr->shop_name_en, sizeof(arr->shop_name_en), "Test Shop!");
strcpy_s(arr->shop_nickname, sizeof(arr->shop_nickname), "Test Shop"); strcpy_s(arr->shop_nickname, sizeof(arr->shop_nickname), "Test Shop");
@ -320,14 +320,14 @@ static HRESULT STDMETHODCALLTYPE IAuth_GetMuchaAuthResponse(IAuth FAR *This, str
} }
// Another struct // Another struct
static HRESULT STDMETHODCALLTYPE IAuth_Func19(IAuth FAR *This, struct amcus_arr19 *arr) static HRESULT STDMETHODCALLTYPE IAuth_Func19(IAuth FAR *This, struct mucha_updater_state *arr)
{ {
// dprintf("IAuth: %s hit!\n", __func__); // dprintf("IAuth: %s hit!\n", __func__);
memset(arr, 0, sizeof(*arr)); memset(arr, 0, sizeof(*arr));
if (!is_init) { if (!is_init) {
return E_ACCESSDENIED; return E_ACCESSDENIED;
} }
arr->Member0 = 1; // if this isn't 1 taiko thinks it isn't auth'd arr->state = 1; // if this isn't 1 taiko thinks it isn't auth'd
return 1; return 1;
} }
@ -486,4 +486,4 @@ IAuth iauth_stub_object = {
.lpVtbl = &iauth_vtbl, .lpVtbl = &iauth_vtbl,
}; };
IAuth *iauth_stub = &iauth_stub_object; IAuth *iauth_stub = &iauth_stub_object;

View File

@ -9,63 +9,206 @@
void iauth_set_config(struct amcus_config *cfg); void iauth_set_config(struct amcus_config *cfg);
enum daemon_state {
DAEMON_UNKNOWN,
DAEMON_GET_HOP,
DAEMON_GET_TIP,
DAEMON_GET_AIP,
DAEMON_GET_NET_INFO,
DAEMON_INIT,
DAEMON_AUTH_START,
DAEMON_AUTH_BUSY,
DAEMON_AUTH_RETRY,
DAEMON_DL,
DAEMON_EXPORT,
DAEMON_IMPORT,
DAEMON_CONSUME_CHARGE,
DAEMON_NOTIFY_CHARGE,
DAEMON_CHECK_LAN,
DAEMON_IDLE,
DAEMON_FINALIZE,
DAEMON_BUSY
};
enum daemon_error {
ERR_CHARGE_COMM = -14,
ERR_DL_TIMEOUT = -11,
ERR_SYSTEM,
ERR_NO_INIT,
ERR_NO_AUTH,
ERR_AUTH_COMM,
ERR_AUTH_TIMEOUT,
ERR_AUTH,
ERR_INIT,
ERR_CFG,
ERR_NETWORK,
ERR_UNKNOWN,
ERR_NONE
};
enum line_type {
TYPE_UNKNOWN,
TYPE_FFT,
TYPE_DSL,
TYPE_ETC,
TYPE_MOBILE
};
enum link_state {
STATE_UNKNOWN,
STATE_OK,
STATE_NG,
STATE_CHECK
};
enum updater_state {
UPDATE_STATE_UNKNOWN,
UPDATE_NOT_NECESSASSARY,
UPDATE_NOT_YET_PERM_DATA,
UPDATE_NOT_YET_PERM,
UPDATE_NOT_YET_DATA,
UPDATE_STATE_UNAVAILABLE
};
enum auth_type {
AUTH_TYPE_OFFLINE,
AUTH_TYPE_ALLNET,
AUTH_TYPE_NBLINE,
AUTH_TYPE_CHARGE_NORMAL,
AUTH_TYPE_CHARGE_MONTHLY
};
enum daemon_mode {
DAEMON_MODE_UNKNOWN,
DAEMON_MODE_SERVER,
DAEMON_MODE_CLIENT,
DAEMON_MODE_STANDALONE,
};
enum amdaemon_info {
AMDAEMON_UNINITIALIZED,
AMDAEMON_AUTH_UNKNOWN,
AMDAEMON_AUTH_OK,
AMDAEMON_AUTH_NG,
AMDAEMON_AUTH_NG_REGIST,
AMDAEMON_AUTH_NG_BOARD,
AMDAEMON_AUTH_NG_PLACE,
AMDAEMON_AUTH_NG_RESPONSE,
AMDAEMON_AUTH_NG_OTHER
};
enum dlexec_state {
DLEXEC_UNKNOWN = 25,
DLEXEC_NONE,
DLEXEC_PROC,
DLEXEC_STOP,
DLEXEC_STOPPING,
};
enum dlstep_state {
DLSTEP_UNKNOWN = 30,
DLSTEP_NONE,
DLSTEP_IDLE,
DLSTEP_PARTIMG_CHECK,
DLSTEP_STOP_REQ,
DLSTEP_LAN_VERINFO,
DLSTEP_LAN_CHECKCODE,
DLSTEP_LAN_IMGCHUNK,
DLSTEP_WAN_CHECKCODE,
DLSTEP_WAN_IMGCHUNK,
};
enum dllan_state {
DLLAN_UNKNOWN = 40,
DLLAN_NONE,
DLLAN_REQ,
DLLAN_DISABLE,
DLLAN_SERVER_NOTHING,
DLLAN_SERVER_VER_NOTHING,
DLLAN_SERVER_CHECKCODE_NOTHING,
DLLAN_SERVER_IMGCHUNK_NOTHING,
DLLAN_COMPLETE
};
enum dlwan_state {
DLWAN_UNKNOWN = 49,
DLWAN_NONE,
DLWAN_REQ,
DLWAN_COMPLETE,
DLWAN_DISABLE,
DLWAN_WANENV_INVALID,
DLWAN_BASICAUTHKEY_INVALID,
DLWAN_SERVER_VERINFO_NOTHING,
DLWAN_SERVER_VERINFO_VERSION_NOTHING,
};
enum daemon_io_info {
DAEMON_IO_UNKNOWN = 58,
DAEMON_IO_NONE,
DAEMON_IO_IDLE,
DAEMON_IO_EXPORT,
DAEMON_IO_IMPORT,
DAEMON_IO_FAIL,
DAEMON_IO_SUCCESS,
};
// member names are wrong lol // member names are wrong lol
/* Memory Size: 20 */ /* Memory Size: 20 */
struct Struct_1 { struct allnet_state {
/* Offset: 0 */ /* ENUM32 */ uint32_t Member0; /* Offset: 0 */ /* ENUM32 */ uint32_t state;
/* Offset: 4 */ /* ENUM32 */ uint32_t Member4; /* Offset: 4 */ /* ENUM32 */ uint32_t error;
/* Offset: 8 */ int32_t Member8; /* Offset: 8 */ int32_t auth_state;
/* Offset: 12 */ int32_t MemberC; /* Offset: 12 */ int32_t auth_count;
/* Offset: 16 */ int32_t Member10; /* Offset: 16 */ int32_t last_error;
}; };
/* Memory Size: 144 */ /* Memory Size: 144 */
struct Struct_2 { struct mucha_state {
/* Offset: 0 */ /* ENUM32 */ uint32_t Member0; /* Offset: 0 */ /* ENUM32 */ uint32_t state;
/* Offset: 4 */ /* ENUM32 */ uint32_t Member4; /* Offset: 4 */ /* ENUM32 */ uint32_t error;
/* Offset: 8 */ int32_t Member8; /* Offset: 8 */ int32_t auth_state;
/* Offset: 12 */ int32_t MemberC; /* Offset: 12 */ int32_t auth_count;
/* Offset: 16 */ int32_t Member10; /* Offset: 16 */ int32_t state_dlexec;
/* Offset: 20 */ int32_t Member14; /* Offset: 20 */ int32_t state_dlstep;
/* Offset: 24 */ int32_t Member18; /* Offset: 24 */ int32_t state_dllan;
/* Offset: 28 */ int32_t Member1C; /* Offset: 28 */ int32_t state_dlwan;
/* Offset: 32 */ int32_t Member20; /* Offset: 32 */ int32_t state_io;
/* Offset: 36 */ int16_t cacfg_ver_whole; /* Offset: 36 */ int16_t cacfg_ver_major;
/* Offset: 38 */ int16_t cacfg_ver_decimal; /* Offset: 38 */ int16_t cacfg_ver_minor;
/* Offset: 40 */ int16_t app_ver_whole; /* Offset: 40 */ int16_t app_ver_major;
/* Offset: 42 */ int16_t app_ver_decimal; /* Offset: 42 */ int16_t app_ver_minor;
/* Offset: 44 */ int16_t Member2C; /* Offset: 44 */ int16_t dl_ver_major;
/* Offset: 46 */ int16_t Member2E; /* Offset: 46 */ int16_t dl_ver_minor;
/* Offset: 48 */ int32_t Member30; /* Offset: 48 */ int32_t dl_ver_total;
/* Offset: 52 */ int32_t Member34; /* Offset: 52 */ int32_t dl_ver_done;
/* Offset: 56 */ int64_t Member38; /* Offset: 56 */ int64_t dl_total;
/* Offset: 64 */ int64_t Member40; /* Offset: 64 */ int64_t dl_done;
/* Offset: 72 */ int64_t Member48; /* Offset: 72 */ int64_t dl_pc_done;
/* Offset: 80 */ int64_t Member50; /* Offset: 80 */ int64_t dl_io_total;
/* Offset: 88 */ int64_t Member58; /* Offset: 88 */ int64_t dl_io_done;
/* Offset: 96 */ int32_t Member60; /* Offset: 96 */ int32_t dl_check_complete;
/* Offset: 100 */ int32_t Member64; /* Offset: 100 */ int32_t token_consumed;
/* Offset: 104 */ int32_t Member68; /* Offset: 104 */ int32_t token_charged;
/* Offset: 108 */ int32_t Member6C; /* Offset: 108 */ int32_t token_unit;
/* Offset: 112 */ int32_t Member70; /* Offset: 112 */ int32_t token_lower;
/* Offset: 116 */ int32_t Member74; /* Offset: 116 */ int32_t token_upper;
/* Offset: 120 */ int32_t Member78; /* Offset: 120 */ int32_t token_added;
/* Offset: 124 */ int32_t Member7C; /* Offset: 124 */ int32_t token_month_lower;
/* Offset: 128 */ int32_t Member80; /* Offset: 128 */ int32_t token_month_upper;
/* Offset: 132 */ int32_t Member84; /* Offset: 132 */ int32_t is_forced_boot;
/* Offset: 136 */ int32_t Member88; /* Offset: 136 */ int32_t Member88;
}; };
/* Memory Size: 200 */ /* Memory Size: 200 */
struct amcus_updater_state { struct amcus_state {
/* Offset: 0 */ struct Struct_1 Member0; /* Offset: 0 */ struct allnet_state allnet_state;
/* Offset: 24 */ struct Struct_2 Member18; /* Offset: 24 */ struct mucha_state mucha_state;
/* Offset: 168 */ int64_t clock_status; /* Offset: 168 */ int64_t clock_status;
/* Offset: 176 */ int64_t name_resolution_timeout; /* Offset: 176 */ int64_t name_resolution_timeout;
/* Offset: 184 */ /* ENUM32 */ uint32_t network_mode; /* Offset: 184 */ /* ENUM32 */ uint32_t auth_type;
/* Offset: 188 */ /* ENUM32 */ uint32_t cab_type; /* Offset: 188 */ /* ENUM32 */ uint32_t cab_mode;
/* Offset: 192 */ /* ENUM32 */ uint32_t amauth_init_state; /* Offset: 192 */ /* ENUM32 */ uint32_t state;
/* Offset: 196 */ /* ENUM32 */ uint32_t MemberC4; /* Offset: 196 */ /* ENUM32 */ uint32_t err;
}; };
/* Memory Size: 316 */ /* Memory Size: 316 */
@ -82,7 +225,7 @@ struct amcus_version_info {
}; };
/* Memory Size: 168 */ /* Memory Size: 168 */
struct amcus_cab_config { struct amcus_network_state {
char mode[16]; char mode[16];
char pcbid[16]; char pcbid[16];
char dongle_serial[16]; char dongle_serial[16];
@ -95,9 +238,9 @@ struct amcus_cab_config {
int hop_count; int hop_count;
uint32_t line_type; uint32_t line_type;
uint32_t line_status; uint32_t line_status;
uint32_t unknown9C; uint32_t content_router_status;
uint32_t router_status; uint32_t shop_router_status;
uint32_t unknownA4; uint32_t hop_status;
}; };
/* Memory Size: 3808 */ /* Memory Size: 3808 */
@ -141,15 +284,15 @@ struct mucha_boardauth_resp {
}; };
/* Memory Size: 56 */ /* Memory Size: 56 */
struct amcus_arr19 { struct mucha_updater_state {
/* Offset: 0 */ /* ENUM32 */ uint64_t Member0; /* Offset: 0 */ /* ENUM32 */ uint64_t state;
/* Offset: 8 */ int64_t Member8; /* Offset: 8 */ int64_t enforce_done;
/* Offset: 16 */ int64_t Member10; /* Offset: 16 */ int64_t enforce_total;
/* Offset: 24 */ int64_t Member18; /* Offset: 24 */ int64_t distrib_done;
/* Offset: 32 */ int64_t Member20; /* Offset: 32 */ int64_t distrib_total;
/* Offset: 40 */ int64_t Member28; /* Offset: 40 */ int64_t exec_total;
/* Offset: 48 */ int16_t Member30; /* Offset: 48 */ int16_t dl_ver_major;
/* Offset: 50 */ int16_t Member32; /* Offset: 50 */ int16_t dl_ver_minor;
/* Offset: 52 */ int16_t Member34; /* Offset: 52 */ int16_t Member34;
/* Offset: 54 */ int16_t Member36; /* Offset: 54 */ int16_t Member36;
}; };
@ -185,8 +328,8 @@ DECLARE_INTERFACE_(IAuth,CStdStubBuffer)
STDMETHOD_(LONG,Func6)() PURE; STDMETHOD_(LONG,Func6)() PURE;
STDMETHOD_(HRESULT,Func7)() PURE; STDMETHOD_(HRESULT,Func7)() PURE;
STDMETHOD_(HRESULT,Func8)() PURE; STDMETHOD_(HRESULT,Func8)() PURE;
STDMETHOD_(HRESULT,GetUpdaterState)(THIS_ struct amcus_updater_state *arr) PURE; STDMETHOD_(HRESULT,GetUpdaterState)(THIS_ struct amcus_state *arr) PURE;
STDMETHOD_(HRESULT,GetCabinetConfig)(THIS_ struct amcus_cab_config *arr) PURE; STDMETHOD_(HRESULT,GetCabinetConfig)(THIS_ struct amcus_network_state *arr) PURE;
STDMETHOD_(HRESULT,GetVersionInfo)(THIS_ struct amcus_version_info *arr) PURE; STDMETHOD_(HRESULT,GetVersionInfo)(THIS_ struct amcus_version_info *arr) PURE;
STDMETHOD_(HRESULT,Func12)() PURE; STDMETHOD_(HRESULT,Func12)() PURE;
STDMETHOD_(HRESULT,Func13)() PURE; STDMETHOD_(HRESULT,Func13)() PURE;
@ -195,7 +338,7 @@ DECLARE_INTERFACE_(IAuth,CStdStubBuffer)
STDMETHOD_(HRESULT,Func16)() PURE; STDMETHOD_(HRESULT,Func16)() PURE;
STDMETHOD_(HRESULT,Func17)() PURE; STDMETHOD_(HRESULT,Func17)() PURE;
STDMETHOD_(HRESULT,GetMuchaAuthResponse)(THIS_ struct mucha_boardauth_resp *arr) PURE; STDMETHOD_(HRESULT,GetMuchaAuthResponse)(THIS_ struct mucha_boardauth_resp *arr) PURE;
STDMETHOD_(HRESULT,Func19)(THIS_ struct amcus_arr19 *arr) PURE; STDMETHOD_(HRESULT,Func19)(THIS_ struct mucha_updater_state *arr) PURE;
STDMETHOD_(HRESULT,Func20)() PURE; STDMETHOD_(HRESULT,Func20)() PURE;
STDMETHOD_(HRESULT,Func21)() PURE; STDMETHOD_(HRESULT,Func21)() PURE;
STDMETHOD_(HRESULT,Func22)() PURE; STDMETHOD_(HRESULT,Func22)() PURE;