#include #include #include #include #include #include #include "trackvw.h" //Helper functions BOOL ListTreeView(HWND hwnd); BOOL ListEditView(HWND hwnd, LPSTR lpUrl); LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam); //extern HINSTANCE g_hinst; static char lpPfx[] = "Log:"; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "UrlTrack Cache Viewer"; HWND hwnd; MSG msg; WNDCLASSEX wndclass; HACCEL hAccel; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (GRAY_BRUSH); wndclass.lpszMenuName = MAKEINTRESOURCE(TRACKMENU); wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); hwnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); hAccel = LoadAccelerators (hInstance, "TrackVw"); while(GetMessage(&msg, NULL, 0, 0)) { if(!TranslateAccelerator(hwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInstance; static HWND hwndTreeView, hwndEdit = NULL; RECT rcClientWnd, rcTreeWnd, rcEditWnd = {0}; switch(iMsg) { case WM_CREATE: { OleInitialize(NULL); InitCommonControls(); hInstance = ((LPCREATESTRUCT) lParam)->hInstance; GetClientRect(hwnd, &rcClientWnd); rcTreeWnd.right = rcClientWnd.right / 2; // Set the right edge for the Tree control to one half the client window space rcTreeWnd.bottom = rcClientWnd.bottom; rcEditWnd.left = rcTreeWnd.right + 5; // Leave space from the left frame for the resize bar rcEditWnd.right = rcClientWnd.right - (rcTreeWnd.right + 5); rcEditWnd.bottom = rcClientWnd.bottom; hwndTreeView = CreateWindow(WC_TREEVIEW, "", WS_VISIBLE | WS_CHILD | TVS_HASLINES | WS_BORDER | TVS_SHOWSELALWAYS, 0, 0, rcTreeWnd.right, rcTreeWnd.bottom, hwnd, (HMENU) 1, hInstance, NULL); if (!hwndTreeView) break; ShowWindow(hwndTreeView, SW_SHOW); hwndEdit = CreateWindow("EDIT", NULL, WS_BORDER | WS_VISIBLE | WS_CHILD | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE, rcEditWnd.left, 0, rcEditWnd.right, rcEditWnd.bottom, hwnd, (HMENU) 2, hInstance, NULL); if (!hwndEdit) break; ShowWindow(hwndEdit, SW_SHOW); if (!ListTreeView(hwndTreeView)) break; SetFocus(hwndTreeView); return 0; } case WM_SIZE: { GetClientRect(hwnd, &rcClientWnd); rcTreeWnd.right = rcClientWnd.right / 2; // Set the right edge for the Tree control to one half the client window space rcTreeWnd.bottom = rcClientWnd.bottom; rcEditWnd.left = rcTreeWnd.right + 3; // Leave space from the left frame for the resize bar rcEditWnd.right = rcClientWnd.right - (rcTreeWnd.right + 5); rcEditWnd.bottom = rcClientWnd.bottom; SetWindowPos(hwndTreeView, HWND_TOP, 0, 0, rcTreeWnd.right, rcTreeWnd.bottom, SWP_SHOWWINDOW); SetWindowPos(hwndEdit, HWND_TOP, rcEditWnd.left, 0, rcEditWnd.right, rcEditWnd.bottom, SWP_SHOWWINDOW); break; } case WM_COMMAND: { switch(LOWORD(wParam)) { case ID_EXIT: { SendMessage(hwnd, WM_CLOSE, 0, 0L); return 0; } case ID_REFRESH: { TreeView_DeleteAllItems(hwndTreeView); if (!ListTreeView(hwndTreeView)) break; } } break; } case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) { case TVN_SELCHANGED: { // Get the Text of the URL which was selected, add our prefix to it // and get the CacheEntryInfo for the URL. Then open the file it points to // and display the contents in the edit window. char lpTempBuf[MY_MAX_STRING_LEN]; char lpUrl[MY_MAX_STRING_LEN]; ((NM_TREEVIEW *)lParam)->itemNew.mask = TVIF_TEXT; ((NM_TREEVIEW *)lParam)->itemNew.pszText = lpTempBuf; ((NM_TREEVIEW *)lParam)->itemNew.cchTextMax = MY_MAX_STRING_LEN; TreeView_GetItem(hwndTreeView, &((NM_TREEVIEW *)lParam)->itemNew); lstrcpy(lpUrl, lpPfx); lstrcat(lpUrl, ((NM_TREEVIEW *)lParam)->itemNew.pszText); ListEditView(hwndEdit, lpUrl); break; } //TVN_SELCHANGED } break; } case WM_DESTROY: { OleUninitialize(); PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, iMsg, wParam, lParam); } BOOL ListTreeView(HWND hwnd) { LPSTR lpUrl = NULL; BYTE cei[MY_CACHE_ENTRY_INFO_SIZE]; LPINTERNET_CACHE_ENTRY_INFO lpCE = (LPINTERNET_CACHE_ENTRY_INFO)cei; HTREEITEM htItem = NULL; DWORD cbSize = MY_CACHE_ENTRY_INFO_SIZE; HANDLE hCacheEntry = NULL; TV_ITEM tvi = {0}; TV_INSERTSTRUCT tvins = {0}; hCacheEntry = FindFirstUrlCacheEntry(lpPfx, lpCE, &cbSize); if (!hCacheEntry) return FALSE; // sanity check char sztmp[10]; lstrcpyn(sztmp, lpCE->lpszSourceUrlName, lstrlen(lpPfx)+1); if (lstrcmpi(sztmp, lpPfx)) { FindCloseUrlCache(hCacheEntry); return TRUE; } lpUrl = (LPSTR)GlobalAlloc(GPTR, MY_MAX_STRING_LEN); // add the length of the cache prefix string to the source url // name to skip the cache prefix .. was the quickest way to strip // the prefix from the url. lstrcpy(lpUrl, lpCE->lpszSourceUrlName+lstrlen(lpPfx)); tvi.mask = TVIF_HANDLE | TVIF_TEXT; tvi.pszText = lpUrl; tvi.cchTextMax = lstrlen(lpUrl); tvins.item = tvi; tvins.hInsertAfter = TVI_FIRST; tvins.hParent = TVI_ROOT; TreeView_InsertItem(hwnd, &tvins); for ( ; ; ) { cbSize = MY_CACHE_ENTRY_INFO_SIZE; if (!FindNextUrlCacheEntry(hCacheEntry, lpCE, &cbSize)) break; lstrcpy(lpUrl, lpCE->lpszSourceUrlName+lstrlen(lpPfx)); tvi.pszText = lpUrl; tvi.cchTextMax = lstrlen(lpUrl); tvins.item = tvi; tvins.hInsertAfter = TVI_LAST; TreeView_InsertItem(hwnd, &tvins); } FindCloseUrlCache(hCacheEntry); htItem = TreeView_GetRoot(hwnd); TreeView_SelectItem(hwnd, htItem); if (lpUrl) { GlobalFree(lpUrl); lpUrl = NULL; } return TRUE; } BOOL ListEditView(HWND hwnd, LPSTR lpUrl) { BYTE cei[MY_CACHE_ENTRY_INFO_SIZE]; LPINTERNET_CACHE_ENTRY_INFO lpCE = (LPINTERNET_CACHE_ENTRY_INFO)cei; DWORD cbSize = MY_CACHE_ENTRY_INFO_SIZE; HANDLE hFile = NULL; DWORD dwFileSize = 0; // erase Edit window content Edit_SetText(hwnd, NULL); if(!GetUrlCacheEntryInfo(lpUrl, lpCE, &cbSize)) return FALSE; hFile = CreateFile(lpCE->lpszLocalFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return FALSE; dwFileSize = GetFileSize(hFile, NULL); if (dwFileSize == 0) { CloseHandle(hFile); return FALSE; } LPTSTR lpBuf; DWORD dwBytesRead = 0; lpBuf = (LPTSTR)GlobalAlloc(LPTR, dwFileSize); if (!lpBuf) { CloseHandle(hFile); return FALSE; } if (!ReadFile(hFile, lpBuf, dwFileSize, &dwBytesRead, NULL) || dwBytesRead == 0) { CloseHandle(hFile); return FALSE; } /* // First to avoid displaying any leading spaces we'll walk through the file // we find the first non space character. When we find it, we'll set the file // pointer back 1 so the next time we call ReadFile getting the next byte we'll // be at the non-space character. DWORD dwBytesRead = 0; char ch; do { if (!ReadFile(hFile, &ch, 1, &dwBytesRead, NULL)) { CloseHandle(hFile); return FALSE; } if (dwBytesRead == 0) // reach end-of-file, return now. { CloseHandle(hFile); return TRUE; } } while (ch == ' '); if (ch != ' ') SetFilePointer(hFile, -1, NULL, FILE_CURRENT); // Alloc a buffer large enough for the file plus 2 characters per line LPSTR lpBuffer = NULL; lpBuffer = (LPSTR)GlobalAlloc(GPTR, dwFileSize*2); if (!lpBuffer) { CloseHandle(hFile); return FALSE; } //lpBuffer = "\0"; cbSize = 0; int cch = 0; BOOL bIsLeadChar = FALSE; BOOL bIsSecondChar = FALSE; char tmp[1024]; LPSTR lpTmp = lpBuffer; tmp[0] = '\0'; // N 1 08-19-1997 15:28:45 00:00:05\r\nN 1 08-19-1997 15:30:25 00:00:01 for (;;) { if (!ReadFile(hFile, &ch, 1, &dwBytesRead, NULL)) { // choked here, CloseHandle(hFile); GlobalFree(lpBuffer); return FALSE; } if (dwBytesRead == 0) // reach end-of-file break; switch (ch) { case '\n': wsprintf(tmp, "%c\r\n", ch); lstrcat(lpBuffer, tmp); break; case ' ': tmp[cch] = ch; cch ++; if (bIsLeadChar && bIsSecondChar) { if (cch == 5) { lpTmp[cbSize ++] = '\r'; lpTmp[cbSize ++] = '\n'; for (int i=1; i TEXT(' ')) pszCmdLine++; } // // Skip past any white space preceeding the second token. // while (*pszCmdLine && (*pszCmdLine <= TEXT(' '))) { pszCmdLine++; } si.dwFlags = 0; GetStartupInfoA(&si); i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine, si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT); // Since we now have a way for an extension to tell us when it is finished, // we will terminate all processes when the main thread goes away. ExitProcess(i); // DebugMsg(DM_TRACE, TEXT("c.me: Cabinet main thread exiting without ExitProcess.")); return i; } */