windows-updates-20010819
[openafs.git] / src / WINNT / afs_setup_utils / GetWebDll / GetWebDll.cpp
1 // GetWebDll.cpp : Defines the initialization routines for the DLL.
2 //
3
4 #include "stdafx.h"
5 #include "GetWebDll.h"
6 #include "getwebdllfun.h"
7
8 #ifdef _DEBUG
9 #define new DEBUG_NEW
10 #undef THIS_FILE
11 static char THIS_FILE[] = __FILE__;
12 #endif
13
14 //
15 //      Note!
16 //
17 //              If this DLL is dynamically linked against the MFC
18 //              DLLs, any functions exported from this DLL which
19 //              call into MFC must have the AFX_MANAGE_STATE macro
20 //              added at the very beginning of the function.
21 //
22 //              For example:
23 //
24 //              extern "C" BOOL PASCAL EXPORT ExportedFunction()
25 //              {
26 //                      AFX_MANAGE_STATE(AfxGetStaticModuleState());
27 //                      // normal function body here
28 //              }
29 //
30 //              It is very important that this macro appear in each
31 //              function, prior to any calls into MFC.  This means that
32 //              it must appear as the first statement within the 
33 //              function, even before any object variable declarations
34 //              as their constructors may generate calls into the MFC
35 //              DLL.
36 //
37 //              Please see MFC Technical Notes 33 and 58 for additional
38 //              details.
39 //
40
41 /////////////////////////////////////////////////////////////////////////////
42 // CGetWebDllApp
43
44 BEGIN_MESSAGE_MAP(CGetWebDllApp, CWinApp)
45         //{{AFX_MSG_MAP(CGetWebDllApp)
46                 // NOTE - the ClassWizard will add and remove mapping macros here.
47                 //    DO NOT EDIT what you see in these blocks of generated code!
48         //}}AFX_MSG_MAP
49 END_MESSAGE_MAP()
50
51 /////////////////////////////////////////////////////////////////////////////
52 // CGetWebDllApp construction
53
54 CGetWebDllApp::CGetWebDllApp()
55 {
56         // TODO: add construction code here,
57         // Place all significant initialization in InitInstance
58 }
59
60 /////////////////////////////////////////////////////////////////////////////
61 // The one and only CGetWebDllApp object
62
63 CGetWebDllApp theApp;
64
65
66 LPCTSTR pszURL = NULL;
67 BOOL    bStripMode = FALSE;
68 BOOL    bProgressMode = FALSE;
69 DWORD   dwAccessType = PRE_CONFIG_INTERNET_ACCESS;
70
71 DWORD dwHttpRequestFlags =
72         INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT;
73 //
74 //GET /updateCellServDB.jsp?type=bunk HTTP/1.1
75 //Accept: */*
76 //Accept -Language: en -us
77 //Accept -Encoding: gzip , deflate
78 //User-Agent: ufilerNativeClient/1.0 (1.0; Windows NT)
79 //Host: 192.168.0.1
80 //Connection: Keep -Alive
81
82 const TCHAR szVersion[] =
83         _T("HTTP/1.1");
84
85 const TCHAR szHeaders[] =
86         _T("\
87 Accept: */*\r\n\
88 Accept -Language: en -us\r\n\
89 Accept -Encoding: gzip , deflate\r\n\
90 User-Agent: ufilerNativeClient/1.0 (1.0; Windows NT)\r\n\
91 Host: 192.168.0.1\r\n\
92 Connection: Keep -Alive\r\n");
93
94 CTearSession::CTearSession(LPCTSTR pszAppName, int nMethod)
95         : CInternetSession(pszAppName, 1, nMethod)
96 {
97 }
98
99 void CTearSession::OnStatusCallback(DWORD /* dwContext */, DWORD dwInternetStatus,
100         LPVOID /* lpvStatusInfomration */, DWORD /* dwStatusInformationLen */)
101 {
102         if (!bProgressMode)
103                 return;
104
105         if (dwInternetStatus != INTERNET_STATUS_CONNECTED_TO_SERVER)
106                 AfxMessageBox("Connection Not Made",MB_ICONERROR | MB_OK);
107         return;
108 }
109
110 /////////////////////////////////////////////////////////////////////////////
111 // CTearException -- used if something goes wrong for us
112
113 // TEAR will throw its own exception type to handle problems it might
114 // encounter while fulfilling the user's request.
115
116 IMPLEMENT_DYNCREATE(CTearException, CException)
117
118 CTearException::CTearException(int nCode)
119         : m_nErrorCode(nCode)
120 {
121 }
122
123 void ThrowTearException(int nCode)
124 {
125         CTearException* pEx = new CTearException(nCode);
126         throw pEx;
127 }
128
129 // StripTags() rips through a buffer and removes HTML tags from it.
130 // The function uses a static variable to remember its state in case
131 // a HTML tag spans a buffer boundary.
132
133 void StripTags(LPTSTR pszBuffer)
134 {
135         static BOOL bInTag = FALSE;
136         LPTSTR pszSource = pszBuffer;
137         LPTSTR pszDest = pszBuffer;
138
139         while (*pszSource != '\0')
140         {
141                 if (bInTag)
142                 {
143                         if (*pszSource == '>')
144                                 bInTag = FALSE;
145                         pszSource++;
146                 }
147                 else
148                 {
149                         if (*pszSource == '<')
150                                 bInTag = TRUE;
151                         else
152                         {
153                                 *pszDest = *pszSource;
154                                 pszDest++;
155                         }
156                         pszSource++;
157                 }
158         }
159         *pszDest = '\0';
160 }
161
162
163 extern "C" 
164 __declspec(dllexport) INT GetWebPage(LPSTR lpErrMsg,LPSTR lpFile,LPSTR lpCmdLine)
165 {
166         CString emsg;
167 //      emsg.Format("p1=[%s],p2=[%s]",lpFile,lpCmdLine);
168 //      AfxMessageBox(emsg,MB_ICONERROR | MB_OK);
169         if ((strlen(lpCmdLine)==0) || (strlen(lpFile)==0))
170         {
171                 emsg="Parameter Error";
172                 return 1;
173         }
174
175         int nRetCode = 0;
176
177         CTearSession session(_T("TEAR - MFC Sample App"), dwAccessType);
178         CHttpConnection* pServer = NULL;
179         CHttpFile* pFile = NULL;
180         char *szParm=strstr(lpCmdLine,"?");
181         try
182         {
183                 // check to see if this is a reasonable URL
184                 CFile ofile(lpFile,CFile::modeCreate|CFile::modeWrite);
185
186                 CString strServerName;
187                 CString strObject;
188                 INTERNET_PORT nPort;
189                 DWORD dwServiceType;
190
191                 if (!AfxParseURL(lpCmdLine, dwServiceType, strServerName, strObject, nPort) ||
192                         dwServiceType != INTERNET_SERVICE_HTTP)
193                 {
194                         emsg="Error: can only use URLs beginning with http://";
195                         ThrowTearException(1);
196                 }
197
198                 if (bProgressMode)
199                 {
200                         VERIFY(session.EnableStatusCallback(TRUE));
201                 }
202
203                 pServer = session.GetHttpConnection(strServerName, nPort);
204                 pFile = pServer->OpenRequest(
205                         CHttpConnection::HTTP_VERB_GET,
206                         strObject,              //updateCellServDB.jsp
207                         NULL,                   // URL of document
208                         1,                              // context
209                         NULL,
210                         szVersion,
211                         dwHttpRequestFlags);
212                 pFile->AddRequestHeaders(szHeaders);
213                 pFile->SendRequest();
214
215                 DWORD dwRet;
216                 pFile->QueryInfoStatusCode(dwRet);
217
218                 // if access was denied, prompt the user for the password
219
220                 if (dwRet == HTTP_STATUS_DENIED)
221                 {
222                         DWORD dwPrompt;
223                         dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,
224                                 FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);
225
226                         // if the user cancelled the dialog, bail out
227
228                         if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)
229                         {
230                                 emsg="Access denied: Invalid password";
231                                 ThrowTearException(1);
232                         }
233
234                         pFile->SendRequest();
235                         pFile->QueryInfoStatusCode(dwRet);
236                 }
237
238                 CString strNewLocation;
239                 pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);
240
241                 // were we redirected?
242                 // these response status codes come from WININET.H
243
244                 if (dwRet == HTTP_STATUS_MOVED ||
245                         dwRet == HTTP_STATUS_REDIRECT ||
246                         dwRet == HTTP_STATUS_REDIRECT_METHOD)
247                 {
248                         CString strNewLocation;
249                         pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);
250
251                         int nPlace = strNewLocation.Find(_T("Location: "));
252                         if (nPlace == -1)
253                         {
254                                 emsg="Error: Site redirects with no new location";
255                                 ThrowTearException(2);
256                         }
257
258                         strNewLocation = strNewLocation.Mid(nPlace + 10);
259                         nPlace = strNewLocation.Find('\n');
260                         if (nPlace > 0)
261                                 strNewLocation = strNewLocation.Left(nPlace);
262
263                         // close up the redirected site
264
265                         pFile->Close();
266                         delete pFile;
267                         pServer->Close();
268                         delete pServer;
269
270                         if (bProgressMode)
271                         {
272                                 emsg.Format("Caution: redirected to %s",(LPCTSTR) strNewLocation);
273                         }
274
275                         // figure out what the old place was
276                         if (!AfxParseURL(strNewLocation, dwServiceType, strServerName, strObject, nPort))
277                         {
278                                 emsg="Error: the redirected URL could not be parsed.";
279                                 ThrowTearException(2);
280                         }
281
282                         if (dwServiceType != INTERNET_SERVICE_HTTP)
283                         {
284                                 emsg="Error: the redirected URL does not reference a HTTP resource.";
285                                 ThrowTearException(2);
286                         }
287
288                         // try again at the new location
289                         pServer = session.GetHttpConnection(strServerName, nPort);
290                         pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,
291                                 strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);
292                         pFile->AddRequestHeaders(szHeaders);
293                         pFile->SendRequest();
294
295                         pFile->QueryInfoStatusCode(dwRet);
296                         if (dwRet != HTTP_STATUS_OK)
297                         {
298                                 emsg.Format("Error: Got status code %d",dwRet);
299                                 ThrowTearException(2);
300                         }
301                 }
302
303
304                 TCHAR sz[1024];
305                 while (pFile->ReadString(sz, 1023))
306                 {
307                         if (bStripMode)
308                                 StripTags(sz);
309                         ofile.Write(sz,strlen(sz));
310                 }
311
312                 pFile->Close();
313                 pServer->Close();
314                 ofile.Close();
315         }
316         catch (CInternetException* pEx)
317         {
318                 // catch errors from WinINet
319
320                 TCHAR szErr[1024];
321                 pEx->GetErrorMessage(szErr, 1024);
322
323                 CString emsg;
324                 emsg.Format("Error: (%s)",szErr);
325                 nRetCode = 2;
326                 pEx->Delete();
327         }
328         catch (CFileException* pEx)
329         {
330                 TCHAR szErr[1024];
331                 pEx->GetErrorMessage(szErr, 1024);
332
333                 emsg.Format("File Error: (%s)",szErr);
334                 nRetCode = 2;
335                 pEx->Delete();
336         }
337         catch (CTearException* pEx)
338         {
339                 // catch things wrong with parameters, etc
340
341                 nRetCode = pEx->m_nErrorCode;
342                 pEx->Delete();
343         }
344
345         if (pFile != NULL)
346                 delete pFile;
347         if (pServer != NULL)
348                 delete pServer;
349         session.Close();
350         int len=strlen(lpErrMsg);
351         strncpy(lpErrMsg,emsg,len);
352         lpErrMsg[len]=0;
353         return nRetCode;
354 }
355
356 extern "C" 
357 __declspec(dllexport) INT GetUserLogon(LPSTR lpUserName)
358 {
359         int nRetCode = 1;
360         ULONG nSize=strlen(lpUserName);
361         if (!GetUserName(lpUserName,&nSize)) nRetCode=0;
362         return nRetCode;
363 }
364
365 extern "C" 
366 __declspec(dllexport) INT BrowseFile(HWND hwndOwner,LPSTR lpstrTitle,LPSTR lpFileName,INT size)
367 {
368         char *xptr;
369 //      char msg[256];
370         char *ptr=strrchr(lpFileName,'\\');
371         int nFileOffset=0;
372         int nFileExtension=0;
373         if (ptr)
374                 nFileOffset=ptr-lpFileName+1;
375         else {
376                 ptr=strrchr(lpFileName,':');
377                 if (ptr)
378                         nFileOffset=ptr-lpFileName;
379         }
380         if (ptr==NULL)
381                 ptr=lpFileName;
382         if (xptr=strrchr(ptr,'.'))
383                 nFileExtension=nFileOffset+(xptr-ptr);
384 //      sprintf(msg,"Title: [%s] filename=[%s], %i,%i,%i",lpstrTitle,lpFileName,nFileOffset,nFileExtension,size);
385 //      AfxMessageBox(msg,MB_OK);
386         OPENFILENAME data={
387                 sizeof(OPENFILENAME)    //lStructSize
388                 ,hwndOwner                              //hwndOwner
389                 ,NULL                                   //
390                 ,"*.*"                                  //lpstrFilter
391                 ,NULL                                   //lpstrCustomFilter
392                 ,NULL                                   //nMaxCustFilter
393                 ,0                                              //nFilterIndex
394                 ,lpFileName                     //lpstrFile
395                 ,size                                   //nMaxFile - at least 256 characters
396                 ,NULL                                   //lpstrFileTitle
397                 ,0                                              //nMaxFileTitle
398                 ,NULL                                   //lpstrInitialDir
399                 ,lpstrTitle                             //lpstrTitle
400                 ,OFN_HIDEREADONLY|OFN_PATHMUSTEXIST             //Flags
401                 ,nFileOffset                    //nFileOffset
402                 ,nFileExtension                 //nFileExtension
403                 ,NULL                                   //lpstrDefExt
404                 ,NULL                                   //lCustData
405                 ,NULL                                   //lpfnHook
406                 ,NULL                                   //lpTemplateName
407         };
408         return GetOpenFileName(&data);
409 }