[106] | 1 | //////////////////////////////////////////////////////////// |
---|
[184] | 2 | // Copyright (C) Roman Ryltsov, 2008-2013 |
---|
[106] | 3 | // Created by Roman Ryltsov roman@alax.info |
---|
| 4 | |
---|
| 5 | #pragma once |
---|
| 6 | |
---|
| 7 | #include "UaMobileTools_i.h" |
---|
| 8 | #include "rowinhttp.h" |
---|
| 9 | |
---|
| 10 | //////////////////////////////////////////////////////////// |
---|
| 11 | // CKyivstarUaBalanceQuery |
---|
| 12 | |
---|
| 13 | class ATL_NO_VTABLE CKyivstarUaBalanceQuery : |
---|
| 14 | public CComObjectRootEx<CComMultiThreadModelNoCS>, |
---|
| 15 | public CComCoClass<CKyivstarUaBalanceQuery, &__uuidof(KyivstarUaBalanceQuery)>, |
---|
| 16 | public IDispatchImpl<IKyivstarUaBalanceQuery> |
---|
| 17 | { |
---|
| 18 | public: |
---|
| 19 | enum { IDR = IDR_KYIVSTARUABALANCEQUERY }; |
---|
| 20 | |
---|
| 21 | //DECLARE_REGISTRY_RESOURCEID(IDR) |
---|
| 22 | |
---|
| 23 | DECLARE_PROTECT_FINAL_CONSTRUCT() |
---|
| 24 | |
---|
| 25 | BEGIN_COM_MAP(CKyivstarUaBalanceQuery) |
---|
| 26 | COM_INTERFACE_ENTRY(IKyivstarUaBalanceQuery) |
---|
| 27 | COM_INTERFACE_ENTRY(IDispatch) |
---|
| 28 | END_COM_MAP() |
---|
| 29 | |
---|
| 30 | public: |
---|
| 31 | |
---|
| 32 | private: |
---|
| 33 | mutable CRoCriticalSection m_DataCriticalSection; |
---|
| 34 | CWinHttpSessionHandle m_Session; |
---|
| 35 | CWinHttpConnectionHandle m_Connection; |
---|
| 36 | CStringW m_sNumber; |
---|
| 37 | BOOL m_fBalanceAvailable; |
---|
| 38 | DOUBLE m_fBalance; |
---|
| 39 | |
---|
| 40 | VOID ConnectionNeeded() |
---|
| 41 | { |
---|
| 42 | if(m_Connection) |
---|
| 43 | return; |
---|
| 44 | CWinHttpSessionHandle Session = OpenWinHttpSessionHandle(AtlFormatString(IDS_PROJNAME)); |
---|
| 45 | __E(Session); |
---|
| 46 | CWinHttpConnectionHandle Connection = Session.Connect(CStringW(_T("my.kyivstar.ua"))); |
---|
| 47 | __E(Connection); |
---|
| 48 | m_Session = Session.Detach(); |
---|
| 49 | m_Connection = Connection.Detach(); |
---|
| 50 | } |
---|
| 51 | static SIZE_T ReadResponseContent(CWinHttpRequestHandle& Request, CTempBufferT<CHAR>& pszContentData) |
---|
| 52 | { |
---|
| 53 | static const SIZE_T g_nContentDataCapacity = 64 << 10; |
---|
| 54 | SIZE_T nContentDataCapacity = g_nContentDataCapacity; |
---|
| 55 | DWORD nContentLength = 0; |
---|
| 56 | if(Request.QueryNumberHeader(WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, nContentLength)) |
---|
| 57 | nContentDataCapacity = nContentLength + 1 + 1; // Zero and Safety |
---|
| 58 | pszContentData.Allocate(nContentDataCapacity); |
---|
| 59 | DWORD nContentDataLength = 0; |
---|
[184] | 60 | __E(Request.ReadData(pszContentData, (DWORD) nContentDataCapacity - 1, &nContentDataLength)); |
---|
[106] | 61 | _A(nContentDataLength < g_nContentDataCapacity - 1); |
---|
| 62 | pszContentData[nContentDataLength] = 0; |
---|
| 63 | _A(strlen(pszContentData) == nContentDataLength); |
---|
| 64 | return nContentDataLength; |
---|
| 65 | } |
---|
| 66 | static VOID WriteResponseContent(LPCSTR pszContentData) |
---|
| 67 | { |
---|
| 68 | #if _DEVELOPMENT |
---|
| 69 | _A(pszContentData); |
---|
| 70 | _A(_pAtlModule); |
---|
| 71 | CComCritSecLock<CComCriticalSection> Lock(_pAtlModule->m_csStaticDataInitAndTypeInfo); |
---|
| 72 | static ULONG g_nIndex = 0; |
---|
| 73 | const ULONG nIndex = g_nIndex++; |
---|
| 74 | static CPath g_sDirectory; |
---|
| 75 | if(!_tcslen(g_sDirectory)) |
---|
| 76 | { |
---|
| 77 | TCHAR pszPath[MAX_PATH] = { 0 }; |
---|
| 78 | _W(GetModuleFileName(_AtlBaseModule.GetModuleInstance(), pszPath, DIM(pszPath))); |
---|
| 79 | _W(RemoveFileSpec(pszPath)); |
---|
| 80 | g_sDirectory = pszPath; |
---|
| 81 | } |
---|
| 82 | CPath sPath; |
---|
| 83 | sPath.Combine(g_sDirectory, AtlFormatString(_T("Response-%03d.html"), nIndex)); |
---|
| 84 | CAtlFile File; |
---|
| 85 | __C(File.Create(sPath, GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS)); |
---|
| 86 | __C(File.Write(pszContentData, strlen(pszContentData))); |
---|
| 87 | #else |
---|
| 88 | pszContentData; |
---|
| 89 | #endif |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | public: |
---|
| 93 | // CKyivstarUaBalanceQuery |
---|
| 94 | static CString GetObjectFriendlyName() |
---|
| 95 | { |
---|
| 96 | return _StringHelper::GetLine(IDR, 2); |
---|
| 97 | } |
---|
| 98 | static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw() |
---|
| 99 | { |
---|
| 100 | _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister); |
---|
| 101 | _ATLTRY |
---|
| 102 | { |
---|
| 103 | UpdateRegistryFromResource<CKyivstarUaBalanceQuery>(bRegister); |
---|
| 104 | } |
---|
| 105 | _ATLCATCH(Exception) |
---|
| 106 | { |
---|
| 107 | _C(Exception); |
---|
| 108 | } |
---|
| 109 | return S_OK; |
---|
| 110 | } |
---|
| 111 | CKyivstarUaBalanceQuery() throw() |
---|
| 112 | { |
---|
| 113 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 114 | } |
---|
| 115 | ~CKyivstarUaBalanceQuery() throw() |
---|
| 116 | { |
---|
| 117 | _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this); |
---|
| 118 | } |
---|
| 119 | HRESULT FinalConstruct() throw() |
---|
| 120 | { |
---|
| 121 | m_fBalanceAvailable = FALSE; |
---|
| 122 | return S_OK; |
---|
| 123 | } |
---|
| 124 | VOID FinalRelease() throw() |
---|
| 125 | { |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | // IKyivstarUaBalanceQuery |
---|
| 129 | STDMETHOD(Initialize)(BSTR sNumber, BSTR sPassword) throw() |
---|
| 130 | { |
---|
| 131 | _Z4(atlTraceCOM, 4, _T("sNumber %s, sPassword %s\n"), CString(sNumber), CString(sPassword)); |
---|
| 132 | _ATLTRY |
---|
| 133 | { |
---|
| 134 | ObjectLock Lock(this); |
---|
| 135 | m_fBalanceAvailable = FALSE; |
---|
| 136 | ConnectionNeeded(); |
---|
| 137 | #pragma region Query Token |
---|
| 138 | CStringA sToken; |
---|
| 139 | { |
---|
| 140 | CWinHttpRequestHandle Request = m_Connection.OpenSecureRequest(CStringW(_T("GET")), CStringW(_T("/tbmb/login/show.do"))); |
---|
| 141 | __E(Request); |
---|
| 142 | __E(Request.Send()); |
---|
| 143 | __E(Request.ReceiveResponse()); |
---|
| 144 | DWORD nStatusCode = 0; |
---|
| 145 | __E(Request.QueryNumberHeader(WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, nStatusCode)); |
---|
| 146 | __D(nStatusCode == HTTP_STATUS_OK, MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, nStatusCode)); |
---|
| 147 | CTempBufferT<CHAR> pszContentData; |
---|
| 148 | ReadResponseContent(Request, pszContentData); |
---|
| 149 | WriteResponseContent(pszContentData); |
---|
| 150 | static CRoStaticReA g_TokenExpression( |
---|
| 151 | "\\<input " |
---|
| 152 | "[^\\>]*" |
---|
| 153 | "name=\"org.apache.struts.taglib.html.TOKEN\" " |
---|
| 154 | "[^\\>]*" |
---|
| 155 | "value=\"{[^\"]+}\"", |
---|
| 156 | FALSE); |
---|
| 157 | CRoReMatchContextA MatchContext; |
---|
[184] | 158 | //__D(g_TokenExpression.Match(pszContentData, &MatchContext), E_UNNAMED); |
---|
| 159 | //sToken = MatchContext.GetMatchString(0); |
---|
[106] | 160 | } |
---|
| 161 | #pragma endregion |
---|
| 162 | #pragma region Login and Read Home Page |
---|
| 163 | CString sBalance; |
---|
| 164 | { |
---|
| 165 | CWinHttpPostData PostData; |
---|
[184] | 166 | //PostData.AddValue("org.apache.struts.taglib.html.TOKEN", sToken); |
---|
[106] | 167 | PostData.AddValue("isSubmitted", "false"); |
---|
| 168 | PostData.AddValue("user", CStringA(sNumber)); |
---|
| 169 | PostData.AddValue("password", CStringA(sPassword)); |
---|
| 170 | PostData.AddValue("submit", "yes"); |
---|
| 171 | CWinHttpRequestHandle Request = m_Connection.OpenSecureRequest(CStringW(_T("POST")), CStringW(_T("/tbmb/login/perform.do"))); |
---|
| 172 | __E(Request); |
---|
| 173 | CStringA sPostData(PostData.GetValue()); |
---|
| 174 | __E(Request.Send(PostData.GetHeaders(), -1, const_cast<LPSTR>((LPCSTR) sPostData), sPostData.GetLength(), sPostData.GetLength())); |
---|
| 175 | __E(Request.ReceiveResponse()); |
---|
| 176 | DWORD nStatusCode = 0; |
---|
| 177 | __E(Request.QueryNumberHeader(WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, nStatusCode)); |
---|
| 178 | __D(nStatusCode == HTTP_STATUS_OK, MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, nStatusCode)); |
---|
| 179 | CTempBufferT<CHAR> pszContentData; |
---|
| 180 | ReadResponseContent(Request, pszContentData); |
---|
| 181 | WriteResponseContent(pszContentData); |
---|
| 182 | static CRoStaticReW g_BalanceExpression( |
---|
| 183 | L"\\<nobr\\>((Îñòàòîê íà ñ÷åòó)|(Çàëèøîê íà ðàõóíêó))\\:\\<\\/nobr\\>" |
---|
| 184 | L".+?" |
---|
| 185 | L"\\<b\\>{[^\\<]+}\\<\\/b\\>", |
---|
| 186 | FALSE); |
---|
| 187 | CStringW sContentDataW((LPCSTR) pszContentData); |
---|
| 188 | CRoReMatchContextW MatchContext; |
---|
| 189 | __D(g_BalanceExpression.Match(sContentDataW, &MatchContext), E_UNNAMED); |
---|
| 190 | sBalance = CString(MatchContext.GetMatchString(0)); |
---|
| 191 | } |
---|
| 192 | #pragma endregion |
---|
| 193 | __D(AtlStringToDouble(sBalance, m_fBalance), E_UNNAMED); |
---|
| 194 | m_sNumber = sNumber; |
---|
| 195 | m_fBalanceAvailable = TRUE; |
---|
| 196 | } |
---|
| 197 | _ATLCATCH(Exception) |
---|
| 198 | { |
---|
| 199 | _C(Exception); |
---|
| 200 | } |
---|
| 201 | return S_OK; |
---|
| 202 | } |
---|
| 203 | STDMETHOD(get_Number)(BSTR* psNumber) throw() |
---|
| 204 | { |
---|
| 205 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 206 | _ATLTRY |
---|
| 207 | { |
---|
| 208 | __D(psNumber, E_POINTER); |
---|
| 209 | ObjectLock Lock(this); |
---|
| 210 | CRoCriticalSectionLock DataLock(m_DataCriticalSection); |
---|
| 211 | *psNumber = CComBSTR(m_sNumber).Detach(); |
---|
| 212 | } |
---|
| 213 | _ATLCATCH(Exception) |
---|
| 214 | { |
---|
| 215 | _C(Exception); |
---|
| 216 | } |
---|
| 217 | return S_OK; |
---|
| 218 | } |
---|
| 219 | STDMETHOD(get_Balance)(DOUBLE* pfBalance) throw() |
---|
| 220 | { |
---|
| 221 | _Z4(atlTraceCOM, 4, _T("...\n")); |
---|
| 222 | _ATLTRY |
---|
| 223 | { |
---|
| 224 | __D(pfBalance, E_POINTER); |
---|
| 225 | ObjectLock Lock(this); |
---|
| 226 | CRoCriticalSectionLock DataLock(m_DataCriticalSection); |
---|
| 227 | __D(m_fBalanceAvailable, HRESULT_FROM_WIN32(ERROR_NO_DATA)); |
---|
| 228 | *pfBalance = m_fBalance; |
---|
| 229 | } |
---|
| 230 | _ATLCATCH(Exception) |
---|
| 231 | { |
---|
| 232 | _C(Exception); |
---|
| 233 | } |
---|
| 234 | return S_OK; |
---|
| 235 | } |
---|
| 236 | }; |
---|
| 237 | |
---|
| 238 | OBJECT_ENTRY_AUTO(__uuidof(KyivstarUaBalanceQuery), CKyivstarUaBalanceQuery) |
---|