///////////////////////////////////////////////////////
/*
* inetcpp.cpp *
* Written by Wei Hua
* of Microsoft Developer Support *
* Functions implemented in inetall.cpp *
* MyAllocMem() - memory allocation helper function
* MyFreeMem() - free memory allocated by MyAllocMem
* CMyItemArray::CMyItemArray()
* - CMyItemArray constructor
* CMyItemArray::~CMyItemArray()
* - CMyItemArray destructor
* CMyItemArray::Add() - Add an item to the array
* CMyItemArray::RemoveAll()
* - Remove all items in the array
* CMyItemArray::GetAt()- Get an item given an index
* CMyItemArray::GetSize()
* - Get the size of the array
* WinMain() - WinMain, display our main dialog box
* Dlg_Proc() - Message Proc for the main dialog box
* Dlg_OnInitDialog() - WM_INITDIALOG handler for the main dialog box
* Dlg_OnCommand() - WM_COMMAND handler for the main dialog box
* Dlg_OnDestroy() - WM_DESTROY handler for the main dialog box
* BOOL UpdateUI() - Exchange data between UI and member variables
* FillFtpOrFileObjArray()
* - Enumerate a FTP or FILE URL, and populate a CMyItemArray
* FillTreeControl() - Draw tree structure of a FTP or FILE URL in Treeview Ctrl
* Copyright (C) 1997 Microsoft Corporation. All rights reserved *
*/ //////////////////////////////////////////////////////
#include <windows.h>
#include <windowsx.h> //we use message crackers to make code easier to read
#include <commctrl.h>
#include <tchar.h>
#include <string.h>
#include <wininet.h>
#include "inetall.h"
LPVOID MyAllocMem( DWORD cb)
{
return HeapAlloc(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, cb);
}
BOOL MyFreeMem( LPVOID pMem)
{ return HeapFree(GetProcessHeap(), 0, pMem);
}
//////////////////////////////////////////////////////
//CMyItemArray Implementation functions
CMyItemArray::CMyItemArray()
{
m_nCount = 0;
m_pItemlist = NULL;
}
CMyItemArray::~CMyItemArray()
{ if (m_pItemlist) MyFreeMem(m_pItemlist);
}
int CMyItemArray::Add(ItemAttrib& item) { if (m_nCount%10 == 0) { //Allocating 10 ItemAttrib at a time LPVOID pTemp = MyAllocMem((m_nCount+10) * sizeof (ItemAttrib)); if (!pTemp) return -1; //The called function should check return value CopyMemory (pTemp, m_pItemlist, m_nCount*sizeof(ItemAttrib)); MyFreeMem(m_pItemlist); m_pItemlist = (PItemAttrib)pTemp; } lstrcpy(m_pItemlist[m_nCount].szObjectPath, item.szObjectPath); m_pItemlist[m_nCount].nObjectType = item.nObjectType; return m_nCount++; //return index of the newly added item. Increment count. } void CMyItemArray::RemoveAll() { if (m_pItemlist) MyFreeMem(m_pItemlist); m_pItemlist = NULL; m_nCount = 0; } ItemAttrib CMyItemArray::GetAt(int nIndex) { if (nIndex>=0 && nIndex < m_nCount) return m_pItemlist[nIndex]; else { ItemAttrib nullItem; (nullItem.szObjectPath)[0]='\0'; nullItem.nObjectType = -1; return nullItem; } } int CMyItemArray::GetSize() { return m_nCount; } //End of CMyItemArray Implementation ////////////////////////////////////////////////////// ////////////////////////////////////////////////////// //Declare Dialog callback function. BOOL CALLBACK Dlg_Proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); //WinMain just displays a dialogbox int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { g_hInst = hInstance; InitCommonControls(); if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_INETALL_DIALOG), NULL, (DLGPROC)Dlg_Proc) == -1) MessageBox(NULL, "Failure in creating main dialog window", "Error", MB_OK); return(0); } BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM lParam) { BOOL bRet = FALSE; g_Inet.m_dwSizeHtml = 1024; g_Inet.m_phtml = (LPTSTR)MyAllocMem(g_Inet.m_dwSizeHtml); if (!g_Inet.m_phtml) { MessageBox(hwnd, "Memory Allocation Failure", "Error", MB_OK); return bRet; } bRet = (g_hDlg = hwnd) && (g_Inet.hCheckBoxCern = GetDlgItem(g_hDlg, IDC_CERN)) && (g_Inet.hwndUrl = GetDlgItem(g_hDlg, IDC_URL)) && (g_Inet.hwndPassword = GetDlgItem(g_hDlg, IDC_PASSWORD)) && (g_Inet.hwndUsername = GetDlgItem(g_hDlg, IDC_USERNAME)) && (g_Inet.hTreeViewCtrl = GetDlgItem(g_hDlg, IDC_TREE1)) && (g_Inet.hwndHTML = GetDlgItem(hwnd, IDC_HTML)); if (!bRet) return bRet; //Set inital service to HTTP, and select the option button. g_Inet.m_dwServiceType = SERVICE_TYPE_HTTP; ShowWindow(g_Inet.hCheckBoxCern, SW_HIDE); //CERN check box only shown when doing ftp g_Inet.m_phtml[0]=g_Inet.m_url[0] = g_Inet.m_password[0] = g_Inet.m_username[0] = '\0'; g_Inet.m_cern = TRUE; //Send g_Inet to update UI UpdateUI(FALSE); g_Inet.m_curItem = NULL; //No current selected item in tree control //Set up image list and tree control g_Inet.hImgList = ImageList_Create(16, 15, 0, 3, 2); HBITMAP hBmTemp; for (int iCnt=IDB_BMERR; iCnt<=IDB_BMFILE; iCnt++) { hBmTemp = LoadBitmap(g_hInst, MAKEINTRESOURCE(iCnt)); ImageList_Add(g_Inet.hImgList, hBmTemp, NULL); } TreeView_SetImageList(g_Inet.hTreeViewCtrl, g_Inet.hImgList, TVSIL_NORMAL); TV_INSERTSTRUCT tvstruct; tvstruct.hParent = NULL; tvstruct.hInsertAfter = TVI_FIRST; tvstruct.item.iImage = 0; tvstruct.item.iSelectedImage = 0; tvstruct.item.pszText = _T("Root"); tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; g_Inet.m_curItem= (HTREEITEM)SendMessage(g_Inet.hTreeViewCtrl, TVM_INSERTITEM,0, (LPARAM)(LPTV_INSERTSTRUCT)&tvstruct); g_Inet.m_bRedrawTree = TRUE; return(TRUE); } void Dlg_OnDestroy (HWND hwnd) { if (g_Inet.hImgList) ImageList_Destroy(g_Inet.hImgList); if (g_Inet.m_phtml) MyFreeMem(g_Inet.m_phtml); } void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: EndDialog(hwnd, id); break; case IDC_HTTP: //http option button is clicked. case IDC_FTP: //ftp option button is clicked. case IDC_FILE: //file option button is clicked. g_Inet.m_url[0] = g_Inet.m_password[0] = g_Inet.m_username[0] = g_Inet.m_phtml[0]= '\0'; g_Inet.m_dwServiceType = (id == IDC_HTTP)? SERVICE_TYPE_HTTP: (id == IDC_FTP)?SERVICE_TYPE_FTP : SERVICE_TYPE_FILE; //Show CERN check box for FTP URL only if (id == IDC_FTP) ShowWindow(g_Inet.hCheckBoxCern, SW_SHOW); else ShowWindow(g_Inet.hCheckBoxCern, SW_HIDE); UpdateUI(FALSE); //Send g_Inet to update UI g_Inet.m_itemArray.RemoveAll(); FillTreeControl(); break; case IDC_CERN: //CERN checked box is clicked. g_Inet.m_cern = IsDlgButtonChecked(g_hDlg, IDC_CERN)==BST_CHECKED; break; case IDC_GETDATA: //GetData button is clicked HCURSORhCursor; hCursor = SetCursor(LoadCursor (NULL, IDC_WAIT)); ShowCursor(TRUE); //Get the UI setting to g_Inet UpdateUI(TRUE); g_Inet.m_phtml[0]= '\0'; UpdateUI(FALSE); //cleaning up the html window //strip out white space in url int i=0, j=0; while (g_Inet.m_url[i]) { while (g_Inet.m_url[i] == ' ') i++; g_Inet.m_url[j++] = g_Inet.m_url[i++]; } g_Inet.m_url[j]='\0'; if (!lstrlen(g_Inet.m_url)) { MessageBox(g_hDlg, "You haven't enter a URL yet.", "Error", MB_OK); break; } CharLower(g_Inet.m_url); //change to all lower case if (_tcsstr(g_Inet.m_url, _T("http://")) || _tcsstr(g_Inet.m_url, _T("ftp://")) || _tcsstr(g_Inet.m_url, _T("file://"))) { MessageBox(hwnd, "Don't type method name in the url text box!", g_Inet.m_url, MB_OK); goto CursorBackandBailOut; } if (g_Inet.m_dwServiceType == SERVICE_TYPE_FILE) { //For file url, change all / to \ in the url i=0; while (g_Inet.m_url[i]) { if (g_Inet.m_url[i] == '/') g_Inet.m_url[i] = '\\'; i++; } lstrcpy(szFullUrl, "file://"); lstrcat(szFullUrl, g_Inet.m_url); } else { //For ftp or http, change all \ to / in the url i=0; while (g_Inet.m_url[i]) { if (g_Inet.m_url[i] == '\\') g_Inet.m_url[i] = '/'; i++; } //If the server requires username and password, we will construct a url like this: //http://username:password@server:port/path. //Since we only use InternetOpenUrl, there is no other way to pass in username and //password.Doesn't apply to FILE url. lstrcpy(szFullUrl, g_Inet.m_dwServiceType == SERVICE_TYPE_FTP? "ftp://":"http://"); if (lstrlen(g_Inet.m_username) && lstrlen(g_Inet.m_password)) { lstrcat(szFullUrl,g_Inet.m_username); lstrcat(szFullUrl, ":"); lstrcat(szFullUrl,(LPCTSTR)g_Inet.m_password); lstrcat(szFullUrl, "@"); } lstrcat(szFullUrl,(LPCTSTR)g_Inet.m_url); } //if m_bRedrawTree is FALSE, which means user has clicked a treecontrol item, //we won't redraw the whole tree. We will simply add sub-item to the currnet //selected item. Also if the service HTTP, we don't change tree control at all. if ((g_Inet.m_bRedrawTree && g_Inet.m_dwServiceType != SERVICE_TYPE_HTTP) || g_Inet.m_dwServiceType == SERVICE_TYPE_HTTP) { TreeView_DeleteAllItems( g_Inet.hTreeViewCtrl); TV_INSERTSTRUCT tvstruct; tvstruct.hParent = NULL; tvstruct.hInsertAfter = TVI_FIRST; tvstruct.item.iImage = 0; tvstruct.item.iSelectedImage = 0; tvstruct.item.pszText = g_Inet.m_url; tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; g_Inet.m_curItem = (HTREEITEM)SendMessage(g_Inet.hTreeViewCtrl, TVM_INSERTITEM,0, (LPARAM)(LPTV_INSERTSTRUCT)&tvstruct); } g_Inet.m_bRedrawTree = TRUE; HINTERNET hInternetSession; hInternetSession = InternetOpen(_T("InetAll"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!hInternetSession) { MessageBox(hwnd, "InternetOpen Fails", "Error", MB_OK); goto CursorBackandBailOut; } switch (g_Inet.m_dwServiceType) { case SERVICE_TYPE_HTTP: HINTERNET hInternetFile; //We just download html and text. Modify if needs to download binary file. hInternetFile = InternetOpenUrl(hInternetSession, szFullUrl, NULL, 0, INTERNET_FLAG_TRANSFER_ASCII | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0); if (!hInternetFile) { MessageBox(hwnd, "InternetOpenUrl failed! Check URL or connection", szFullUrl, MB_OK); goto CursorBackandBailOut; } DWORD dwRead; TCHAR szTemp[1024]; int nTimes; nTimes=1; while (InternetReadFile(hInternetFile, (LPVOID)szTemp, 1023, &dwRead)) { if (!dwRead) break; szTemp[dwRead]='\0'; //Enlarge buffer only on a need base if (++nTimes * 1024>(int)g_Inet.m_dwSizeHtml) { LPVOID pTemp = MyAllocMem(g_Inet.m_dwSizeHtml + 1024); if (!pTemp) { MessageBox(hwnd, "Mem alloc fails", "Error", MB_OK); InternetCloseHandle(hInternetFile); g_Inet.m_phtml[0] = '\0'; goto CursorBackandBailOut; } CopyMemory (pTemp, g_Inet.m_phtml, g_Inet.m_dwSizeHtml); g_Inet.m_dwSizeHtml += 1024; MyFreeMem(g_Inet.m_phtml); g_Inet.m_phtml = (LPTSTR)pTemp; } lstrcat(g_Inet.m_phtml, szTemp); } SetWindowText(g_Inet.hwndHTML, g_Inet.m_phtml); InternetCloseHandle(hInternetFile); break; case SERVICE_TYPE_FILE: case SERVICE_TYPE_FTP: //FillFtpOrFileObjArray enumerates and FTP or FILE url, and populates //g_Inet.m_itemArray. if (!FillFtpOrFileObjArray(hInternetSession, szFullUrl)) break; //FillTreeControl draws the treeview control using g_Inet.m_itemArray FillTreeControl(); break; } CursorBackandBailOut: InternetCloseHandle(hInternetSession); UpdateUI(FALSE); ShowCursor(FALSE); SetCursor(hCursor); break; //break for switch id } } BOOL CALLBACK Dlg_Proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fProcessed = TRUE; switch (uMsg) { HANDLE_MSG(hDlg, WM_INITDIALOG, Dlg_OnInitDialog); HANDLE_MSG(hDlg, WM_DESTROY, Dlg_OnDestroy); HANDLE_MSG(hDlg, WM_COMMAND, Dlg_OnCommand); //No message crackers defined in windowsx.h for WM_NOTIFY, so we just handled //it directly. //We only process WM_NOTIFY when TreeView items are double clicked. case WM_NOTIFY: int idCtrl; idCtrl = (int) wParam; LPNMHDR pnmh; pnmh = (LPNMHDR) lParam; if (idCtrl == IDC_TREE1 && pnmh->code == NM_DBLCLK) { g_Inet.m_curItem = TreeView_GetSelection(g_Inet.hTreeViewCtrl); //if it's already root, we don't need to enumerate again. if (! TreeView_GetParent(g_Inet.hTreeViewCtrl, g_Inet.m_curItem)) return fProcessed; TV_ITEM tvItem; tvItem.mask =TVIF_TEXT; tvItem.hItem = g_Inet.m_curItem; tvItem.pszText = g_Inet.m_url; TreeView_GetItem(g_Inet.hTreeViewCtrl, &tvItem); //change UI to have new m_url UpdateUI(FALSE); //if the URL ends with a / or \, it's a directory, we call Dlg_OnCommand directly to //construct new m_itemArray. FillFtpOrFileObjArray //and FillTreeControl will be called by Dlg_OnCommand. TCHAR cRight; cRight = g_Inet.m_url[lstrlen(g_Inet.m_url)-1]; if (cRight =='/' ||cRight =='\\') { g_Inet.m_bRedrawTree = FALSE; Dlg_OnCommand (g_hDlg, IDC_GETDATA, GetDlgItem(g_hDlg, IDC_GETDATA),0); } else { //if it's a file, we are downloading it. if (g_Inet.m_dwServiceType == SERVICE_TYPE_FTP) { HINTERNET hInternetFile, hInternetSession; hInternetSession = InternetOpen(_T("InetAll"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!hInternetSession) { MessageBox(g_hDlg, "InternetOpen Fails", "Error", MB_OK); return fProcessed; } UpdateUI(TRUE); lstrcpy(szFullUrl, g_Inet.m_dwServiceType == SERVICE_TYPE_FTP? "ftp://":"http://"); if (lstrlen(g_Inet.m_username) && lstrlen(g_Inet.m_password)) { lstrcat(szFullUrl,g_Inet.m_username); lstrcat(szFullUrl, ":"); lstrcat(szFullUrl,(LPCTSTR)g_Inet.m_password); lstrcat(szFullUrl, "@"); } lstrcat(szFullUrl,(LPCTSTR)g_Inet.m_url); DeleteFile("c:\\deleteme"); HANDLE f; DWORD dwRead; //download the file to c:\deleteme f= CreateFile("c:\\deleteme", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL); if (f== INVALID_HANDLE_VALUE) { MessageBox (hDlg, "Can't open c:\\deleteme to write! Enough free space on C:???", szFullUrl, MB_OK); return fProcessed; } hInternetFile = InternetOpenUrl(hInternetSession,(LPCTSTR)szFullUrl, NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0); if (!hInternetFile) { CloseHandle(f); return fProcessed; } TCHAR szTemp[1024]; while (InternetReadFile(hInternetFile, (LPVOID)szTemp, 1024, &dwRead)) { if (!dwRead) break; DWORD dwWritten; WriteFile(f, (LPVOID)szTemp, dwRead, &dwWritten, NULL); } CloseHandle(f); InternetCloseHandle(hInternetFile); InternetCloseHandle(hInternetSession); MessageBox(g_hDlg, "The url is downloaded in c:\\deleteme!", szFullUrl, MB_OK); }//////////// else { ///file type url DeleteFile("c:\\deleteme"); if (CopyFile( g_Inet.m_url,// pointer to name of an existing file "c:\\deleteme",// pointer to filename to copy to FALSE // flag for operation if file exists )) MessageBox(g_hDlg, "The url is downloaded in c:\\deleteme!", g_Inet.m_url, MB_OK); else { MessageBox(g_hDlg, "CopyFile failed!", g_Inet.m_url, MB_OK); } } } //Double click will actually collapse a tree. To expand it in double click event //we will simply post a TVM_EXPAND message to the treeview control. PostMessage(g_Inet.hTreeViewCtrl, TVM_EXPAND, (WPARAM) (UINT) TVE_EXPAND, (LPARAM) g_Inet.m_curItem); } break; default: fProcessed = FALSE; break; } return(fProcessed); } //Update UI or Collect input from UI //bDirection FALSE g_Inet to UI //bDirection TRUE UI to g_Inet BOOL UpdateUI(BOOL bDirection) { BOOL bRet = FALSE; if (bDirection) //Get UI Input to g_Inet { if (BST_CHECKED ==IsDlgButtonChecked(g_hDlg, IDC_CERN)) g_Inet.m_cern = TRUE; else g_Inet.m_cern = FALSE; if (BST_CHECKED ==IsDlgButtonChecked(g_hDlg, IDC_HTTP)) g_Inet.m_dwServiceType == SERVICE_TYPE_HTTP; if (BST_CHECKED ==IsDlgButtonChecked(g_hDlg, IDC_FTP)) g_Inet.m_dwServiceType == SERVICE_TYPE_FTP; if (BST_CHECKED ==IsDlgButtonChecked(g_hDlg, IDC_FILE)) g_Inet.m_dwServiceType == SERVICE_TYPE_FILE; bRet = GetDlgItemText(g_hDlg, IDC_URL, g_Inet.m_url, MAX_STRING_SIZE) && GetDlgItemText(g_hDlg, IDC_USERNAME, g_Inet.m_username, MAX_STRING_SIZE) && GetDlgItemText(g_hDlg, IDC_PASSWORD, g_Inet.m_password, MAX_STRING_SIZE); } else //Update UI from g_Inet { int nService; if (g_Inet.m_dwServiceType == SERVICE_TYPE_HTTP) nService = IDC_HTTP; else if (g_Inet.m_dwServiceType == SERVICE_TYPE_FTP) nService = IDC_FTP; else nService = IDC_FILE; bRet = CheckRadioButton(g_hDlg, IDC_HTTP, IDC_FILE, nService) && SetWindowText(g_Inet.hwndUrl, g_Inet.m_url) && SetWindowText(g_Inet.hwndPassword, g_Inet.m_password) && SetWindowText(g_Inet.hwndUsername, g_Inet.m_username);; bRet = bRet && SetWindowText(g_Inet.hwndHTML, g_Inet.m_phtml); SendMessage(g_Inet.hCheckBoxCern, BM_SETCHECK, g_Inet.m_cern, 0); } return bRet; } //Enumerate strURL, and populate g_Inet.m_itemArray BOOL FillFtpOrFileObjArray(HINTERNET hInternetSession, LPTSTR strURL) { BOOL bRet = FALSE; if (!hInternetSession) return bRet; if (g_Inet.m_dwServiceType == SERVICE_TYPE_HTTP) { MessageBox(g_hDlg, "only ftp and file url needs enumeration!", "Error", MB_OK); return bRet; } ItemAttrib tempObj; g_Inet.m_itemArray.RemoveAll(); if (g_Inet.m_dwServiceType == SERVICE_TYPE_FTP) //////// start_if_ftp { //CERN or NO CERN we will download HTML anyway. HINTERNET hInternetFile; hInternetFile = InternetOpenUrl(hInternetSession, szFullUrl, NULL, 0, INTERNET_FLAG_TRANSFER_ASCII | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0); DWORD dwRead; TCHAR szTemp[1024]; int nTimes; nTimes=1; while (InternetReadFile(hInternetFile, (LPVOID)szTemp, 1023, &dwRead)) { if (!dwRead) break; szTemp[dwRead]='\0'; if (++nTimes * 1024>(int)g_Inet.m_dwSizeHtml) { LPVOID pTemp = MyAllocMem(g_Inet.m_dwSizeHtml + 1024); if (!pTemp) { MessageBox(g_hDlg, "Mem alloc fails", "Error", MB_OK); InternetCloseHandle(hInternetFile); g_Inet.m_phtml[0] = '\0'; break; } CopyMemory (pTemp, g_Inet.m_phtml, g_Inet.m_dwSizeHtml); g_Inet.m_dwSizeHtml += 1024; MyFreeMem(g_Inet.m_phtml); g_Inet.m_phtml = (LPTSTR)pTemp; } lstrcat(g_Inet.m_phtml, szTemp); } SetWindowText(g_Inet.hwndHTML, g_Inet.m_phtml); InternetCloseHandle(hInternetFile); //If direct access to FTP server, we will use //InternetOpenUrl(INTERNET_FLAG_RAW_DATA) and InternetFindNextFile //to enumerate the sub directories and files if (!g_Inet.m_cern) //start_if_no_cern { WIN32_FIND_DATA wfd; HINTERNET hInternetFind = InternetOpenUrl(hInternetSession,(LPCTSTR)strURL, NULL, 0, INTERNET_FLAG_RAW_DATA| INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0); if (!InternetFindNextFile (hInternetFind, &wfd)) { bRet = FALSE; //Actually this may or may not be a failure. MessageBox(g_hDlg, "No files or sub-directories under this url directory", strURL, MB_OK); return bRet; } do { LPCTSTR strFileName; if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { strFileName = (LPCTSTR) &wfd.cFileName; if (strFileName[0] == '.') continue; lstrcpy(tempObj.szObjectPath, g_Inet.m_url); if (strURL[lstrlen(strURL)-1] != '/') lstrcat(tempObj.szObjectPath, "/"); lstrcat (tempObj.szObjectPath, strFileName); if (tempObj.szObjectPath[lstrlen(tempObj.szObjectPath)-1] != '/' ) lstrcat(tempObj.szObjectPath, "/"); tempObj.nObjectType = 1; g_Inet.m_itemArray.Add(tempObj); } else { strFileName = (LPCTSTR) &wfd.cFileName; lstrcpy(tempObj.szObjectPath , g_Inet.m_url); if (strURL[lstrlen(strURL)-1] != '/') lstrcat(tempObj.szObjectPath, "/"); lstrcat(tempObj.szObjectPath, strFileName); tempObj.nObjectType = 0; g_Inet.m_itemArray.Add(tempObj); } } while (InternetFindNextFile (hInternetFind, &wfd)); InternetCloseHandle (hInternetFind); } //end_if_no_cern else { //start_if_cern LPTSTR strTemp; TCHAR strTempUrl[MAX_STRING_SIZE]; strTemp = g_Inet.m_phtml; //we have the html file listings in the strTemp, we just need to parse it //a sample html is provided at the bottom of this file. Note that the parsing //code may not work with proxies other than MS Proxy server. while (TRUE) { int nPos; TCHAR strLeft[] = "<A HREF="; TCHAR strRight[] = ">"; nPos = _tcsstr(strTemp, strLeft) - strTemp; if (nPos < 0) break; strTemp = strTemp + nPos +lstrlen(strLeft)+1; nPos = _tcsstr(strTemp, strRight) - strTemp; for (int i=0; i<nPos-1; i++) strTempUrl[i]=strTemp[i]; strTempUrl[nPos-1] = '\0'; strTemp = strTemp +i +lstrlen(strRight); if (strTempUrl[0] == '.') continue; if (g_Inet.m_url[lstrlen(g_Inet.m_url)-1] != '/') { g_Inet.m_url[lstrlen(g_Inet.m_url)] ='/'; g_Inet.m_url[lstrlen(g_Inet.m_url)+1] ='\0'; } TCHAR strServerName[256]; i=0; while (TRUE) { strServerName[i]= g_Inet.m_url[i]; if (g_Inet.m_url[i] == '/') { strServerName[i] = '\0'; break; } i++; } lstrcpy(tempObj.szObjectPath, strServerName); lstrcat(tempObj.szObjectPath, strTempUrl); if (strTempUrl[lstrlen(strTempUrl)-1] == '/' ) tempObj.nObjectType = 1; else tempObj.nObjectType = 0; g_Inet.m_itemArray.Add(tempObj); } if (!g_Inet.m_itemArray.GetSize()){ MessageBox(g_hDlg, "No files or sub-directories under the url", g_Inet.m_url, MB_OK); return bRet; } }//end_if_cern }////end_if_ftp else { //start_if_file TCHAR strFileSpec[MAX_STRING_SIZE]; lstrcpy(strFileSpec, g_Inet.m_url); //trying to determine if it's a single machine name to enumerate, or //it's already a unc name. LPTSTR szTempRight; //in case user type in \\machine name in url text box, szTempRight = strFileSpec+2; int i=0; BOOL bServerNameOnly; bServerNameOnly= TRUE; for (i=0; i<lstrlen(szTempRight)-1; i++) { if (szTempRight[i] == '\\') { bServerNameOnly = FALSE; break; } } if (bServerNameOnly) { //user enters a single machine name, we will enumerate the shares. lstrcpy(g_Inet.m_url, "\\\\"); int i=0; while (strFileSpec[i] == '\\') i++; lstrcat(g_Inet.m_url, (LPTSTR)(strFileSpec + i)); if (g_Inet.m_url[lstrlen(g_Inet.m_url)-1] == '\\') g_Inet.m_url[lstrlen(g_Inet.m_url)-1] = '\0'; //now the g_Inet.m_url is "\\server name NETRESOURCE nr; nr.dwScope = RESOURCE_GLOBALNET; nr.dwType = RESOURCETYPE_ANY; nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER; nr.dwUsage = RESOURCEUSAGE_CONTAINER; nr.lpLocalName = NULL; nr.lpRemoteName = g_Inet.m_url; nr.lpComment = NULL; nr.lpProvider = NULL; LPVOID pMem = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, 16384); if (!pMem) { MessageBox(g_hDlg, "Not enough memory to allocate for WNetEnumResource",g_Inet.m_url, MB_OK ); return bRet; } HANDLE hWNetEnum=NULL; DWORD dwStatus = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_CONNECTABLE, &nr, &hWNetEnum); if (dwStatus != NO_ERROR) { DWORD dwErr = GetLastError(); MessageBox(g_hDlg, "WNetOpenEnum failed", g_Inet.m_url, MB_OK ); HeapFree(GetProcessHeap(), 0, pMem); return bRet; } do { DWORD dwEntries; DWORD dwBuffSize; dwEntries =1; dwBuffSize= 16384; dwStatus = WNetEnumResource(hWNetEnum, &dwEntries, pMem, &dwBuffSize); if (dwStatus == NO_ERROR) { lstrcpy(tempObj.szObjectPath, ((LPNETRESOURCE)pMem)->lpRemoteName); lstrcat(tempObj.szObjectPath, "\\"); tempObj.nObjectType = 1; g_Inet.m_itemArray.Add(tempObj); } } while (dwStatus == NO_ERROR); if (dwStatus != ERROR_NO_MORE_ITEMS) { MessageBox(g_hDlg, "WNetEnumResource failed",g_Inet.m_url, MB_OK); MyFreeMem(pMem); WNetCloseEnum(hWNetEnum); return bRet; } MyFreeMem(pMem); WNetCloseEnum(hWNetEnum); //we are done with enumerating shares on a file server. return bRet = TRUE; } lstrcpy(strFileSpec, "\\\\"); i=0; while (g_Inet.m_url[i]=='\\') //skip starting \ in m_url { i++; } lstrcat(strFileSpec, g_Inet.m_url+i); //Now strFileSpec is a UNC such as \\server\share\filedirectory\... WIN32_FIND_DATA fd; HANDLE hFind = NULL; if ((hFind = FindFirstFile ((LPCTSTR) strFileSpec, &fd)) == INVALID_HANDLE_VALUE) { if (strFileSpec[lstrlen(strFileSpec)-1] != '\\') lstrcat(strFileSpec, "\\"); lstrcpy(g_Inet.m_url, strFileSpec); lstrcat(strFileSpec, "*.*"); if ((hFind = FindFirstFile ((LPCTSTR) strFileSpec, &fd)) == INVALID_HANDLE_VALUE) { MessageBox(g_hDlg, "No files or sub-directories under the url", g_Inet.m_url, MB_OK); return bRet; } } do { if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { (LPCTSTR) &fd.cFileName; if ( ((LPCTSTR) &fd.cFileName)[0] == '.') continue; lstrcpy(tempObj.szObjectPath, g_Inet.m_url); lstrcat(tempObj.szObjectPath, (LPCTSTR) &fd.cFileName); lstrcat(tempObj.szObjectPath, "\\"); tempObj.nObjectType = 1; g_Inet.m_itemArray.Add(tempObj); } else { lstrcpy(tempObj.szObjectPath, g_Inet.m_url); lstrcat(tempObj.szObjectPath, (LPCTSTR) &fd.cFileName); tempObj.nObjectType = 0; g_Inet.m_itemArray.Add(tempObj); } } while (FindNextFile (hFind, &fd)); FindClose (hFind); } //end_if_file bRet = TRUE; //happy here. return bRet; } //Draw tree structure of a FTP or FILE URL in //treeview Ctrl using g_Inet.m_itemArray void FillTreeControl() { TV_INSERTSTRUCT tvstruct; int nItem; nItem = g_Inet.m_itemArray.GetSize(); HTREEITEM hChildItem=NULL, hNextChildItem=NULL; if (!nItem){ TreeView_DeleteAllItems( g_Inet.hTreeViewCtrl); tvstruct.hParent = NULL; tvstruct.hInsertAfter = TVI_FIRST; tvstruct.item.iImage = 0; tvstruct.item.iSelectedImage = 0; tvstruct.item.pszText = _T("Root"); tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; SendMessage(g_Inet.hTreeViewCtrl, TVM_INSERTITEM,0, (LPARAM)(LPTV_INSERTSTRUCT)&tvstruct); return; } int nBMID; //Remove all old items under the selected item hChildItem = TreeView_GetChild(g_Inet.hTreeViewCtrl, g_Inet.m_curItem); while (hChildItem) { hNextChildItem = TreeView_GetNextSibling(g_Inet.hTreeViewCtrl, hChildItem); TreeView_DeleteItem(g_Inet.hTreeViewCtrl, hChildItem); hChildItem = hNextChildItem; } //add new items for (int i=0; i<nItem; i++) { nBMID = ((g_Inet.m_itemArray.GetAt(i)).nObjectType==0)?2:1; tvstruct.hParent = g_Inet.m_curItem; tvstruct.hInsertAfter = TVI_LAST; tvstruct.item.iImage = nBMID; tvstruct.item.iSelectedImage = nBMID; tvstruct.item.pszText = (g_Inet.m_itemArray.GetAt(i)).szObjectPath; tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT; SendMessage(g_Inet.hTreeViewCtrl, TVM_INSERTITEM,0, (LPARAM)(LPTV_INSERTSTRUCT)&tvstruct); } //Make sure the tree under the selected item is expanded. if (g_Inet.m_curItem) { TreeView_EnsureVisible(g_Inet.hTreeViewCtrl, g_Inet.m_curItem); TreeView_Expand(g_Inet.hTreeViewCtrl, g_Inet.m_curItem, TVE_EXPAND); } } //A typical HTML wrapper for file listing a in ftp url from MS Proxy Server //which is CERN-compatible proxy. /* <HTML> <HEAD> <TITLE>FTP root at ftp.microsoft.com</TITLE> </HEAD> <BODY> <H1>FTP root at ftp.microsoft.com</H1> <HR> <H4><PRE> This is FTP.MICROSOFT.COM. Please see the dirmap.txt file for more information.
</PRE></H4> <HR> <PRE> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/access/">access</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/dosword/">dosword</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/excel/">excel</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/games/">games</A> 10/08/94 12:00AM <DIR> <A HREF="/deskapps/GEN_INFO/">GEN_INFO</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/homeapps/">homeapps</A> 03/12/97 10:23PM <DIR> <A HREF="/deskapps/kids/">kids</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/miscapps/">miscapps</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/mmapps/">mmapps</A> 08/28/96 12:00AM <DIR> <A HREF="/deskapps/MONEY/">MONEY</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/office/">office</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/powerpt/">powerpt</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/project/">project</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/publishr/">publishr</A> 08/30/94 12:00AM 1,791 <A HREF="/deskapps/readme.txt">readme.txt</A> 08/24/94 12:00AM <DIR> <A HREF="/deskapps/word/">word</A> 08/28/96 12:00AM <DIR> <A HREF="/deskapps/WORKS/">WORKS</A> </PRE> <HR> </BODY> </HTML> */ /////////////////////// End Of File ////////////////////////
#include "stdafx.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HINTERNET hOpen, hConnect, hReq;
hOpen = InternetOpen("SimpleGet", INTERNET_OPEN_TYPE_PRECONFIG, NULL, 0, 0);
if(!hOpen)
{
cout << "hopen " << GetLastError() << endl;
return 0;
}
// try the following in InternetConnect to see the problem.
hConnect = InternetConnect(hOpen, "www.microsoft.com/learning/", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if(!hConnect)
{
cout << "hconnect " << GetLastError() << endl;
return 0;
}
hReq = HttpOpenRequest(hConnect, "GET", "", "HTTP/1.1", NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
if(!hReq)
{
cout << "hreq " << GetLastError() << endl;
return 0;
}
if(HttpSendRequest(hReq, NULL, 0, NULL, 0))
{
DWORD dwSize = 0;
char Data[1024] = "\0";
DWORD dwCode, dwCodeSize;
dwCodeSize = sizeof(DWORD);
if(!HttpQueryInfo(hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwCodeSize, NULL))
{
cout << "queryinfo " << GetLastError() << endl;
return 0;
}
else
{
cout << "Status Code: " << dwCode << endl;
}
do
{
InternetReadFile(hReq, (LPVOID)Data, 1023, &dwSize);
if(0!=dwSize)
{
Data[dwSize]='\0';
cout << Data;
}
ZeroMemory(Data, 1024);
}while (dwSize !=0);
}
else
{
cout << "SendRequest error " << GetLastError() << endl;
}
return 0;
}