source: trunk/Utilities/UaMobileTools/KyivstarUaBalanceQuery.h @ 106

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