source: trunk/Utilities/UaMobileTools/KyivstarUaBalanceQuery.h

Last change on this file was 184, checked in by roman, 8 years ago

Update to follow website changes

  • Property svn:keywords set to Id
File size: 7.5 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2013
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
13class ATL_NO_VTABLE CKyivstarUaBalanceQuery : 
14        public CComObjectRootEx<CComMultiThreadModelNoCS>,
15        public CComCoClass<CKyivstarUaBalanceQuery, &__uuidof(KyivstarUaBalanceQuery)>,
16        public IDispatchImpl<IKyivstarUaBalanceQuery>
17{
18public:
19        enum { IDR = IDR_KYIVSTARUABALANCEQUERY };
20
21//DECLARE_REGISTRY_RESOURCEID(IDR)
22
23DECLARE_PROTECT_FINAL_CONSTRUCT()
24
25BEGIN_COM_MAP(CKyivstarUaBalanceQuery)
26        COM_INTERFACE_ENTRY(IKyivstarUaBalanceQuery)
27        COM_INTERFACE_ENTRY(IDispatch)
28END_COM_MAP()
29
30public:
31
32private:
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;
60                __E(Request.ReadData(pszContentData, (DWORD) nContentDataCapacity - 1, &nContentDataLength));
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
92public:
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;
158                                //__D(g_TokenExpression.Match(pszContentData, &MatchContext), E_UNNAMED);
159                                //sToken = MatchContext.GetMatchString(0);
160                        }
161                        #pragma endregion
162                        #pragma region Login and Read Home Page
163                        CString sBalance;
164                        {
165                                CWinHttpPostData PostData;
166                                //PostData.AddValue("org.apache.struts.taglib.html.TOKEN", sToken);
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
238OBJECT_ENTRY_AUTO(__uuidof(KyivstarUaBalanceQuery), CKyivstarUaBalanceQuery)
Note: See TracBrowser for help on using the repository browser.