// // Implementation file for the CListViews Class // #include #include "stdafx.h" #include "CListViews.h" #include "resource.h" #include #include #include #include #include #include #define FILENAME_FIELD_WIDTH 10 #define VERSION_FIELD_WIDTH 13 #define DATE_FIELD_WIDTH 9 #define CURRENT_FIELD_WIDTH 8 #define PATH_FIELD_WIDTH 13 BOOL bUserAbort; BOOL bSuccess; HWND hDlgPrint; #define BUFFER_SIZE 255 LRESULT CListViews::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled,HWND m_hWnd) { LPNMHDR lpnmh = (LPNMHDR) lParam; NM_LISTVIEW *pnm = (NM_LISTVIEW *)lParam; LPNMITEMACTIVATE lpnmia; HWND hwndListView = ::GetDlgItem(m_hWnd, 1001); _TCHAR ItemName[255]; _TCHAR FileName[255]; _TCHAR TempProduct[255]; if ( lpnmh->idFrom != 1001) { return 0; } switch(lpnmh->code) { case LVN_ITEMCHANGED: lpnmia = (LPNMITEMACTIVATE)lParam; switch (m_CurrentView) { case VIEW_ALL_FILE: ListView_GetItemText(hwndListView, lpnmia->iItem,0,TempProduct,255); ListView_GetItemText(hwndListView, lpnmia->iItem,1,ItemName, 255); _tcscpy(CurrentProductName,TempProduct); _tcscpy(m_CurrentHotfix, ItemName); _tcscpy (m_ProductName,_T("\0")); AddItemsBottom(); break; case VIEW_ALL_HOTFIX: ListView_GetItemText(hwndListView, lpnmia->iItem,0,TempProduct,255); ListView_GetItemText(hwndListView, lpnmia->iItem,1,ItemName, 255); _tcscpy(CurrentProductName,TempProduct); _tcscpy(m_CurrentHotfix, ItemName); _tcscpy (m_ProductName,_T("\0")); AddItemsBottom(); break; case VIEW_BY_FILE: ListView_GetItemText(hwndListView, lpnmia->iItem,0,ItemName, 255); ListView_GetItemText(hwndListView, lpnmia->iItem,0,FileName, 255); _tcscpy(CurrentFile, FileName); _tcscpy(m_CurrentHotfix, ItemName); AddItemsBottom(); break; case VIEW_BY_HOTFIX: ListView_GetItemText(hwndListView, lpnmia->iItem,0,ItemName, 255); _tcscpy(m_CurrentHotfix, ItemName); AddItemsBottom(); break; } // end switch //_tcscpy(m_CurrentHotfix, ItemName); // Process LVN_COLUMNCLICK to sort items by column. break; case LVN_COLUMNCLICK: { //Message(TEXT("NotifyListView: LVN_COLUMNCLICK"), -1, NULL); ListView_SortItemsEx( lpnmh->hwndFrom, CompareFunc, pnm->iSubItem); m_SortOrder = !m_SortOrder; break; } break; } // end switch DWORD Status = GetState(); ::EnableWindow(m_WebButton,FALSE); ::EnableWindow(m_UninstButton,FALSE); ::EnableWindow(m_RptButton,FALSE); if (Status & UNINSTALL_OK) ::EnableWindow(m_UninstButton,TRUE); if (Status & HOTFIX_SELECTED) ::EnableWindow(m_WebButton,TRUE); if (Status & OK_TO_PRINT) ::EnableWindow(m_RptButton,TRUE); // SetFocus(m_WebButton); bHandled = TRUE; return 0; } BOOL CListViews::Initialize( _TCHAR * ComputerName) { LVCOLUMN Col; _TCHAR TempComputer[255]; _tcscpy(m_ProductName,_T("\0")); EnableWindow(m_WebButton, FALSE); EnableWindow(m_UninstButton,FALSE); for (DWORD i = 0; i< 3000000;i++) ; _tcscpy ( m_ComputerName, ComputerName); if (DataBase) FreeDatabase(); DataBase = NULL; Col.mask = LVCF_WIDTH; SendMessage(TopList, LVM_DELETEALLITEMS, 0, 0); SendMessage(TopList, WM_SETREDRAW, FALSE, 0); while (ListView_GetColumn(TopList,0,&Col)) ListView_DeleteColumn(TopList,0); // Clear the bottom list SendMessage(BottomList, LVM_DELETEALLITEMS, 0, 0); SendMessage(BottomList, WM_SETREDRAW, FALSE, 0); while (ListView_GetColumn(BottomList,0,&Col)) ListView_DeleteColumn(BottomList,0); SendMessage(BottomList, WM_SETREDRAW,TRUE, 0); Col.mask = LVCF_FMT | LVCF_TEXT; Col.fmt = LVCFMT_LEFT; Col.pszText = _T("Hotfix Manager"); ListView_InsertColumn(TopList,0,&Col); LVITEM LvItem; LvItem.mask = LVIF_TEXT; LvItem.iItem = 0; _TCHAR Message[255]; _tcscpy(Message,_T("\0")); LoadString(m_hInst,IDS_RETRIEVE_DATA,Message,255); LvItem.pszText = Message; LvItem.iSubItem = 0; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW,TRUE, 0); DataBase = BuildDatabase (ComputerName); DWORD dwLength = 255; GetComputerName(TempComputer, &dwLength); if (_tcscmp(ComputerName, TempComputer)) m_bRemoted = TRUE; else m_bRemoted = FALSE; _tcscpy (m_ProductName,_T("\0")); _tcscpy(m_CurrentHotfix, _T("\0")); AddItemsTop(); AddItemsBottom(); return TRUE; } BOOL CListViews::Initialize( HWND ParentWnd, HINSTANCE hInst,_TCHAR * ComputerName, HWND WebButton, HWND UninstButton, HWND RptButton) { m_bRemoted = FALSE; m_WebButton = WebButton; m_UninstButton = UninstButton; m_RptButton = RptButton; m_hInst = hInst; m_CurrentView = VIEW_ALL_HOTFIX; _tcscpy (m_ProductName,_T("\0")); DWORD dwStyle = WS_CHILD | WS_BORDER | LVS_AUTOARRANGE | // LVS_SORTDESCENDING| LVS_REPORT | LVS_SHAREIMAGELISTS | WS_VISIBLE | LVS_SHOWSELALWAYS ; TopList = CreateWindowEx( WS_EX_CLIENTEDGE, // ex style WC_LISTVIEW, // class name - defined in commctrl.h NULL, // window text dwStyle, // style 0, // x position 0, // y position 0, // width 0, // height ParentWnd, // parent (HMENU)1001, // ID hInst, // instance NULL); // no extra data dwStyle |= LVS_NOSORTHEADER; BottomList = CreateWindowEx( WS_EX_CLIENTEDGE, // ex style WC_LISTVIEW, // class name - defined in commctrl.h NULL, // window text dwStyle, // style 0, // x position 0, // y position 0, // width 0, // height ParentWnd, // parent NULL, // ID hInst, // instance NULL); // no extra data ListView_SetExtendedListViewStyle(TopList, LVS_EX_FULLROWSELECT); ListView_SetExtendedListViewStyle(BottomList, LVS_EX_FULLROWSELECT); _tcscpy (m_ProductName,_T("\0")); _tcscpy (m_CurrentHotfix,_T("\0")); return TRUE; } BOOL CListViews::Resize(RECT *rc) { MoveWindow( TopList, rc->left, rc->top, rc->right - rc->left, (rc->bottom -50) /2 - 2, TRUE); MoveWindow( BottomList, rc->left, ( rc->bottom-50) / 2 , rc->right - rc->left, rc->bottom-50 - (rc->bottom -50) /2, TRUE); return TRUE; } BOOL CListViews::ShowLists(RECT * rc) { ShowWindow(TopList,TRUE); ShowWindow(BottomList, TRUE); Resize(rc); return TRUE; } BOOL CListViews::AddItemsTop() { // Top View First LVITEM LvItem; LVCOLUMN Col; _TCHAR szBuffer[255]; PHOTFIXLIST CurrentHotfix; PFILELIST CurrentFile; int itemnum = 0; // int iSubItem = 0; PPRODUCT CurrentEntry; LvItem.iItem = itemnum; LvItem.mask = LVIF_TEXT ; Col.mask = LVCF_WIDTH; SendMessage(TopList, LVM_DELETEALLITEMS, 0, 0); SendMessage(TopList, WM_SETREDRAW, FALSE, 0); while (ListView_GetColumn(TopList,0,&Col)) ListView_DeleteColumn(TopList,0); Col.cx =100; Col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; Col.fmt = LVCFMT_LEFT; switch (m_CurrentView ) { case VIEW_ALL_HOTFIX: // default for primary node. { CurrentEntry = DataBase; LoadString(m_hInst,IDS_PRODUCT_NAME,szBuffer ,255); Col.pszText = _T("Product Name"); ListView_InsertColumn(TopList,0,&Col); LoadString(m_hInst,IDS_ARTICLE_NUMBER,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,1,&Col); LoadString(m_hInst,IDS_DESCRIPTION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,2,&Col); LoadString(m_hInst,IDS_SERVICE_PACK,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,3,&Col); LoadString(m_hInst,IDS_INSTALLED_BY,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,4,&Col); LoadString(m_hInst,IDS_INSTALL_DATE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,5,&Col); LoadString(m_hInst,IDS_UPDATE_TYPE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,6,&Col); LvItem.mask = LVIF_TEXT ; if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW, TRUE, 0); return FALSE; } while (CurrentEntry != NULL) { // first insert the product name // Now walk down the hotfix list. CurrentHotfix = CurrentEntry->HotfixList; while (CurrentHotfix != NULL) { LvItem.mask |= LVIF_PARAM; LvItem.iItem = itemnum; LvItem.pszText = CurrentEntry->ProductName; LvItem.iSubItem = 0; ListView_InsertItem(TopList,&LvItem); ListView_SetItemText(TopList, itemnum, 1, CurrentHotfix->HotfixName); ListView_SetItemText(TopList, itemnum, 2 , CurrentHotfix->Description); ListView_SetItemText(TopList, itemnum, 3, CurrentHotfix->ServicePack); ListView_SetItemText(TopList, itemnum, 4, CurrentHotfix->InstalledBy); ListView_SetItemText(TopList, itemnum, 5, CurrentHotfix->InstalledDate); ListView_SetItemText(TopList, itemnum, 6, CurrentHotfix->Type); if (itemnum == 0) { // MessageBox(NULL,CurrentEntry->ProductName, _T("Selecting Product"),MB_OK); _tcscpy(CurrentProductName,CurrentEntry->ProductName); _tcscpy(m_CurrentHotfix, CurrentEntry->HotfixList->HotfixName ); ListView_SetItemState(TopList, 0,LVIS_SELECTED,LVIS_STATEIMAGEMASK | LVIS_SELECTED); ::EnableWindow(m_WebButton,FALSE); ::EnableWindow(m_UninstButton,FALSE); ::EnableWindow(m_RptButton,FALSE); DWORD Status = GetState(); if (Status & UNINSTALL_OK) ::EnableWindow(m_UninstButton,TRUE); if (Status & HOTFIX_SELECTED) ::EnableWindow(m_WebButton,TRUE); if (Status & OK_TO_PRINT) ::EnableWindow(m_RptButton,TRUE); SetFocus(m_WebButton); } itemnum++; CurrentHotfix = CurrentHotfix->pNext; } CurrentEntry = CurrentEntry->pNext; } } break; case VIEW_ALL_FILE: // View all of the files updated by all products. CurrentEntry = DataBase; // MessageBox(NULL,_T("Viewing all by file"),NULL,MB_OK); LoadString(m_hInst,IDS_PRODUCT_NAME,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,0,&Col); LoadString(m_hInst,IDS_ARTICLE_NUMBER,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,1,&Col); LoadString(m_hInst,IDS_FILE_NAME,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,2,&Col); LoadString(m_hInst,IDS_FILE_DATE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,3,&Col); LoadString(m_hInst,IDS_FILE_CURRENT,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,4,&Col); LoadString(m_hInst,IDS_FILE_VERSION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,5,&Col); LoadString(m_hInst,IDS_FILE_LOCATION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,6,&Col); if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL,_T("No Database"),NULL,MB_OK); return FALSE; } LvItem.mask = LVIF_TEXT; while (CurrentEntry != NULL) { // first insert the product name // Now walk down the hotfix list. CurrentHotfix = CurrentEntry->HotfixList; while (CurrentHotfix != NULL) { CurrentFile = CurrentHotfix->FileList; LvItem.iItem = itemnum; while (CurrentFile != NULL) { LvItem.pszText = CurrentEntry->ProductName; LvItem.iSubItem = 0; ListView_InsertItem(TopList,&LvItem); ListView_SetItemText(TopList, itemnum, 1, CurrentHotfix->HotfixName); ListView_SetItemText(TopList, itemnum, 2 , CurrentFile->FileName); ListView_SetItemText(TopList, itemnum, 3, CurrentFile->FileDate); ListView_SetItemText(TopList, itemnum, 4, CurrentFile->IsCurrent); ListView_SetItemText(TopList, itemnum, 5, CurrentFile->FileVersion); ListView_SetItemText(TopList, itemnum, 6, CurrentFile->InstallPath); itemnum++; CurrentFile = CurrentFile->pNext; LvItem.iItem = itemnum; } CurrentHotfix = CurrentHotfix->pNext; } CurrentEntry = CurrentEntry->pNext; } break; case VIEW_BY_HOTFIX: CurrentEntry = DataBase; if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW, TRUE, 0); return FALSE; } LoadString(m_hInst,IDS_ARTICLE_NUMBER,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,0,&Col); LoadString(m_hInst,IDS_DESCRIPTION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,1,&Col); LoadString(m_hInst,IDS_SERVICE_PACK,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,2,&Col); LoadString(m_hInst,IDS_INSTALLED_BY,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,3,&Col); LoadString(m_hInst,IDS_INSTALL_DATE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,4,&Col); LoadString(m_hInst,IDS_UPDATE_TYPE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,5,&Col); LvItem.mask = LVIF_TEXT; while ( _tcscmp(CurrentEntry->ProductName, m_ProductName) && (CurrentEntry != NULL)) CurrentEntry = CurrentEntry->pNext; // first insert the product name // Now walk down the hotfix list. if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW, TRUE, 0); return FALSE; } CurrentHotfix = CurrentEntry->HotfixList; while (CurrentHotfix != NULL) { LvItem.iItem = itemnum; LvItem.pszText = CurrentHotfix->HotfixName; LvItem.iSubItem = 0; ListView_InsertItem(TopList,&LvItem); ListView_SetItemText(TopList, itemnum, 1 , CurrentHotfix->Description); ListView_SetItemText(TopList, itemnum, 2, CurrentHotfix->ServicePack); ListView_SetItemText(TopList, itemnum, 4, CurrentHotfix->InstalledDate); ListView_SetItemText(TopList, itemnum, 3, CurrentHotfix->InstalledBy); ListView_SetItemText(TopList, itemnum, 5, CurrentHotfix->Type); if (itemnum == 0) { // MessageBox(NULL,CurrentEntry->ProductName, _T("Selecting Product"),MB_OK); _tcscpy(CurrentProductName,CurrentEntry->ProductName); _tcscpy(m_CurrentHotfix, CurrentEntry->HotfixList->HotfixName ); ListView_SetItemState(TopList, 0,LVIS_SELECTED,LVIS_STATEIMAGEMASK | LVIS_SELECTED); ::EnableWindow(m_WebButton,FALSE); ::EnableWindow(m_UninstButton,FALSE); ::EnableWindow(m_RptButton,FALSE); DWORD Status = GetState(); if (Status & UNINSTALL_OK) ::EnableWindow(m_UninstButton,TRUE); if (Status & HOTFIX_SELECTED) ::EnableWindow(m_WebButton,TRUE); if (Status & OK_TO_PRINT) ::EnableWindow(m_RptButton,TRUE); SetFocus(m_WebButton); } itemnum++; CurrentHotfix = CurrentHotfix->pNext; } break; case VIEW_BY_FILE: // Displays all files modified by all updates for the current product. CurrentEntry = DataBase; LoadString(m_hInst,IDS_ARTICLE_NUMBER,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,1,&Col); LoadString(m_hInst,IDS_FILE_NAME,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,2,&Col); LoadString(m_hInst,IDS_FILE_DATE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,3,&Col); LoadString(m_hInst,IDS_FILE_CURRENT,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,4,&Col); LoadString(m_hInst,IDS_FILE_VERSION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,5,&Col); LoadString(m_hInst,IDS_FILE_LOCATION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(TopList,6,&Col); if (CurrentEntry == FALSE) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW, TRUE, 0); return FALSE; } LvItem.mask = LVIF_TEXT; // first insert locate the product name while ( (_tcscmp(CurrentEntry->ProductName,m_ProductName) )&& (CurrentEntry != NULL)) CurrentEntry = CurrentEntry->pNext; // Now walk down the hotfix list. if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(TopList,&LvItem); SendMessage(TopList, WM_SETREDRAW, TRUE, 0); return FALSE; } CurrentHotfix = CurrentEntry->HotfixList; while (CurrentHotfix != NULL) { LvItem.iItem = itemnum; CurrentFile = CurrentHotfix->FileList; while (CurrentFile != NULL) { LvItem.pszText = CurrentHotfix->HotfixName; LvItem.iSubItem = 0; ListView_InsertItem(TopList,&LvItem); ListView_SetItemText(TopList, itemnum, 1 , CurrentFile->FileName); ListView_SetItemText(TopList, itemnum, 2, CurrentFile->FileDate); ListView_SetItemText(TopList, itemnum, 3, CurrentFile->IsCurrent); ListView_SetItemText(TopList, itemnum, 4, CurrentFile->FileVersion); ListView_SetItemText(TopList, itemnum, 5, CurrentFile->InstallPath); if (itemnum == 0) { // MessageBox(NULL,CurrentEntry->ProductName, _T("Selecting Product"),MB_OK); _tcscpy(CurrentProductName,CurrentEntry->ProductName); _tcscpy(m_CurrentHotfix, CurrentEntry->HotfixList->HotfixName ); ListView_SetItemState(TopList, 0,LVIS_SELECTED,LVIS_STATEIMAGEMASK | LVIS_SELECTED); ::EnableWindow(m_WebButton,FALSE); ::EnableWindow(m_UninstButton,FALSE); ::EnableWindow(m_RptButton,FALSE); DWORD Status = GetState(); if (Status & UNINSTALL_OK) ::EnableWindow(m_UninstButton,TRUE); if (Status & HOTFIX_SELECTED) ::EnableWindow(m_WebButton,TRUE); if (Status & OK_TO_PRINT) ::EnableWindow(m_RptButton,TRUE); SetFocus(m_WebButton); } itemnum++; LvItem.iItem = itemnum; CurrentFile = CurrentFile->pNext; } CurrentHotfix = CurrentHotfix->pNext; } break; } // end switch SendMessage(TopList, WM_SETREDRAW, TRUE, 0); return TRUE; } BOOL CListViews::AddItemsBottom () { LVITEM LvItem; LVCOLUMN Col; _TCHAR szBuffer[255]; PHOTFIXLIST CurrentHotfix; PFILELIST CurrentFile; int itemnum = 0; // int iSubItem = 0; // int ItemCount = 0; BOOL Done = FALSE; LvItem.mask = LVIF_TEXT; LvItem.iItem = itemnum; PPRODUCT CurrentEntry; // Clear the List View and prepare it for updating.... SendMessage(BottomList, LVM_DELETEALLITEMS, 0, 0); SendMessage(BottomList, WM_SETREDRAW, FALSE, 0); Col.mask =LVCF_WIDTH; while (ListView_GetColumn(BottomList,0,&Col)) ListView_DeleteColumn(BottomList,0); Col.mask = LVCF_TEXT | LVCF_WIDTH; Col.cx = 100; switch (m_CurrentView) { case VIEW_ALL_FILE: case VIEW_BY_FILE: CurrentEntry = DataBase; LoadString(m_hInst,IDS_ARTICLE_NUMBER,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,0,&Col); LoadString(m_hInst,IDS_DESCRIPTION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,1,&Col); LoadString(m_hInst,IDS_SERVICE_PACK,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,2,&Col); LoadString(m_hInst,IDS_INSTALLED_BY,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,3,&Col); LoadString(m_hInst,IDS_INSTALL_DATE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,4,&Col); LoadString(m_hInst,IDS_UPDATE_TYPE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,5,&Col); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); LvItem.mask = LVIF_TEXT; if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL, _T("Database is NULL"),_T("No Items"), MB_OK); return FALSE; } Done = FALSE; if (_tcscmp (m_ProductName,_T("\0"))) { while ( (!Done) && (CurrentEntry != NULL)) { if (!_tcscmp(CurrentEntry->ProductName, m_ProductName)) Done = TRUE; else CurrentEntry = CurrentEntry->pNext; } } else { while ( (!Done) && (CurrentEntry != NULL)) { if (!_tcscmp(CurrentEntry->ProductName, CurrentProductName)) Done = TRUE; else CurrentEntry = CurrentEntry->pNext; } } // Now walk down the hotfix list. if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL, _T("Product Not found or not selected"), _T("No Items"),MB_OK); return FALSE; } CurrentHotfix = CurrentEntry->HotfixList; while ( (CurrentHotfix != NULL) && (_tcscmp(CurrentHotfix->HotfixName, m_CurrentHotfix))) CurrentHotfix = CurrentHotfix->pNext; if (CurrentHotfix != NULL) { LvItem.iItem = itemnum; LvItem.pszText = CurrentHotfix->HotfixName, LvItem.iSubItem = 0; ListView_InsertItem(BottomList,&LvItem); ListView_SetItemText(BottomList, itemnum, 1 , CurrentHotfix->Description); ListView_SetItemText(BottomList, itemnum, 2, CurrentHotfix->ServicePack); ListView_SetItemText(BottomList, itemnum, 3, CurrentHotfix->InstalledBy); ListView_SetItemText(BottomList, itemnum, 4, CurrentHotfix->InstalledDate); ListView_SetItemText(BottomList, itemnum, 5, CurrentHotfix->Type); itemnum++; CurrentHotfix = CurrentHotfix->pNext; } else { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL, _T("No Hotfix Found"), _T("No Items"),MB_OK); return FALSE; } break; case VIEW_ALL_HOTFIX: case VIEW_BY_HOTFIX: CurrentEntry = DataBase; LoadString(m_hInst,IDS_ARTICLE_NUMBER,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,1,&Col); LoadString(m_hInst,IDS_FILE_NAME,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,2,&Col); LoadString(m_hInst,IDS_FILE_DATE,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,3,&Col); LoadString(m_hInst,IDS_FILE_CURRENT,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,4,&Col); LoadString(m_hInst,IDS_FILE_VERSION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,5,&Col); LoadString(m_hInst,IDS_FILE_LOCATION,szBuffer ,255); Col.pszText = szBuffer; ListView_InsertColumn(BottomList,6,&Col); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); LvItem.mask = LVIF_TEXT ; // first insert locate the product name /* if (!_tcscmp(m_ProductName,_T("\0"))) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); return FALSE; } */ if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; LvItem.lParam = NULL; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL, _T("No Database"), _T("No Items"),MB_OK); return FALSE; } if (_tcscmp (m_ProductName,_T("\0"))) { while ( (!Done) && (CurrentEntry != NULL)) { if (!_tcscmp(CurrentEntry->ProductName, m_ProductName)) Done = TRUE; else CurrentEntry = CurrentEntry->pNext; } } else { while ( (!Done) && (CurrentEntry != NULL)) { if (!_tcscmp(CurrentEntry->ProductName, CurrentProductName)) Done = TRUE; else CurrentEntry = CurrentEntry->pNext; } } // Now walk down the hotfix list. if (CurrentEntry == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; LvItem. lParam = NULL; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL, _T("Product Not found or not selected"), _T("No Items"),MB_OK); return FALSE; } CurrentHotfix = CurrentEntry->HotfixList; while ((CurrentHotfix != NULL) && (_tcscmp(CurrentHotfix->HotfixName, m_CurrentHotfix))) CurrentHotfix = CurrentHotfix->pNext; if ( CurrentHotfix == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; LvItem.lParam = NULL; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox(NULL,_T("No Hotfix Found"), _T("No Items"), MB_OK); return FALSE; } if (CurrentHotfix != NULL) { LvItem.iItem = itemnum; CurrentFile = CurrentHotfix->FileList; if (CurrentFile == NULL) { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; LvItem.lParam = NULL; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); // MessageBox (NULL, _T("No Files Found"), _T("No Items"), MB_OK); return FALSE; } while (CurrentFile != NULL) { LvItem.pszText = CurrentHotfix->HotfixName; LvItem.iSubItem = 0; ListView_InsertItem(BottomList,&LvItem); ListView_SetItemText(BottomList, itemnum, 1 , CurrentFile->FileName); ListView_SetItemText(BottomList, itemnum, 2, CurrentFile->FileDate); ListView_SetItemText(BottomList, itemnum, 3, CurrentFile->IsCurrent); ListView_SetItemText(BottomList, itemnum, 4, CurrentFile->FileVersion); ListView_SetItemText(BottomList, itemnum, 5, CurrentFile->InstallPath); itemnum++; LvItem.iItem = itemnum; CurrentFile = CurrentFile->pNext; } CurrentHotfix = CurrentHotfix->pNext; } else { LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(BottomList,&LvItem); SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); return FALSE; } break; default: LoadString(m_hInst,IDS_NO_ITEMS,szBuffer, 255); LvItem.iSubItem = 0; LvItem.pszText = szBuffer; ListView_InsertItem(BottomList,&LvItem); return FALSE; } // end switch SendMessage(BottomList, WM_SETREDRAW, TRUE, 0); return TRUE; } PPRODUCT CListViews::BuildDatabase(_TCHAR * lpszComputerName) { HKEY hPrimaryKey; // Handle of the target system HKLM // _TCHAR szPrimaryPath; // Path to the update key; HKEY hUpdatesKey; // Handle to the updates key. _TCHAR szUpdatesPath[BUFFER_SIZE]; // Path to the udates key DWORD dwUpdatesIndex; // index of current updates subkey DWORD dwBufferSize; // Size of the product name buffer. _TCHAR szProductPath[BUFFER_SIZE]; // Path of the current product key _TCHAR szProductName[BUFFER_SIZE]; // Name of product; also path to product key PPRODUCT pProductList = NULL; // Pointer to the head of the product list. PPRODUCT pNewProdNode; // Pointer used to allocate new nodes in the product list. PPRODUCT pCurrProdNode; // Used to walk the Products List; // Connect to the target registry RegConnectRegistry(lpszComputerName,HKEY_LOCAL_MACHINE, &hPrimaryKey); // insert error handling here...... if (hPrimaryKey != NULL) { // Initialize the primary path not localized since registry keys are not localized. _tcscpy (szUpdatesPath, _T("SOFTWARE\\Microsoft\\Updates")); // open the udates key RegOpenKeyEx(hPrimaryKey,szUpdatesPath, 0, KEY_READ ,&hUpdatesKey); if (hUpdatesKey != NULL) { // Enumerate the Updates key. dwUpdatesIndex = 0; while ( RegEnumKeyEx(hUpdatesKey,dwUpdatesIndex,szProductName, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS) { // Create a node for the current product pNewProdNode = (PPRODUCT) malloc(sizeof(PRODUCTLIST)); _tcscpy(pNewProdNode->ProductName,szProductName); _tcscpy (szProductPath, szProductName); // now get the hotfix for the current product. pNewProdNode->HotfixList = GetHotfixInfo(szProductName, &hUpdatesKey); // Insert the new node into the list. pCurrProdNode=pProductList; if (pCurrProdNode == NULL) // Head of the list { pProductList = pNewProdNode; pProductList->pPrev = NULL; pProductList->pNext = NULL; } else { //Find the end of the list. while (pCurrProdNode->pNext != NULL) pCurrProdNode = pCurrProdNode->pNext; // Now insert the new node at the end of the list. pCurrProdNode->pNext = pNewProdNode; pNewProdNode->pPrev = pCurrProdNode; pNewProdNode->pNext = NULL; } // increment index and clear the szProducts name string for the next pass. dwUpdatesIndex++; _tcscpy (szProductName,_T("\0")); _tcscpy(szProductPath, _T("\0")); dwBufferSize = 255; } } // close the open keys RegCloseKey(hUpdatesKey); RegCloseKey(hPrimaryKey); } // return a pointer to the head of our database. VerifyFiles(pProductList); return pProductList; } void BuildQuery (_TCHAR * Path, _TCHAR * FileName, _TCHAR * Result) { _TCHAR * src; _TCHAR * dest; _TCHAR Temp[255]; src = Path; dest = Temp; while (*src != _T('\0')) { if (*src == _T('\\')) // if we hit a \ character we need to insert four of them in the dest string. { for (int i = 0; i < 4; i++) { *dest = *src; ++dest; } ++src; } else { *dest = *src; ++src; ++dest; } } *dest = _T('\0'); _stprintf(Result,_T("SELECT * from CIM_DataFile WHERE Name = '%s\\\\\\\\%s'"), Temp, FileName); } BOOL VerifyVersion(_TCHAR * Ver1, _TCHAR * Ver2) { _TCHAR *src1; _TCHAR *src2; _TCHAR *dest1, *dest2; _TCHAR temp[20]; _TCHAR temp2[20]; BOOL Done = FALSE; BOOL Status = TRUE; src1 = Ver1; src2 = Ver2; dest1 = temp; dest2 = temp2; if ((!src1) || (!src2)) return FALSE; if (!_tcscmp (src1, src2)) return TRUE; while ( (*src1 != _T('\0')) && (!Done) ) { _tcscpy (temp, _T("\0")); _tcscpy (temp2, _T("\0")); dest1 = temp; dest2 = temp2; // Get the next field of the registry string while( (*src1 != _T('.')) && (*src1 != _T('\0'))) { *dest1 = *src1; ++dest1; ++src1; } if ( *src1 != _T('\0')) ++src1; // skip the . *dest1 = _T('\0'); ++dest1; *dest1= _T('\0'); // Now get the next field from the WMI returned version. while ( (*src2 != _T('.') ) && (*src2 != _T('\0')) ) { *dest2= *src2; ++dest2; ++src2; } if ( *src2 != _T('\0')) ++src2; // skip the . *dest2 = _T('\0'); ++dest2; *dest2= _T('\0'); // Now convert the strings to integers. if ( _ttol (temp) != _ttol (temp2) ) { Status = FALSE; Done = TRUE; } if ( (*src1 == _T('\0')) && (*src2 != _T('\0')) ) { Done = TRUE; Status = FALSE; } if ( ( *src1 != _T('\0')) && (*src2 == _T('\0')) ) { Done = TRUE; Status = FALSE; } } return Status; } VOID CListViews::VerifyFiles(PPRODUCT Database) { PPRODUCT CurrentProduct = NULL; PHOTFIXLIST CurrentHotfix = NULL; PFILELIST CurrentFile = NULL; HRESULT hres; _TCHAR ConnectString[255]; _TCHAR TempBuffer[255]; IWbemLocator *pLoc = 0; hres = CoCreateInstance(CLSID_WbemLocator, 0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID *) &pLoc); if ( FAILED (hres)) { // MessageBox(NULL, _T("Failed to create IWebmLocator Object"),NULL,MB_OK); } else { IWbemServices *pSvc = NULL; // Build the connection string. if (!_tcscmp(m_ComputerName,_T("\0"))) _stprintf(ConnectString,_T("ROOT\\CIMV2")); else _stprintf(ConnectString,_T("\\\\%s\\ROOT\\CIMV2"), m_ComputerName); _TCHAR * ConnectString1; ConnectString1 = SysAllocString(ConnectString); // Connect to the default namespace hres = pLoc->ConnectServer( ConnectString1, NULL,NULL,0,NULL,0,0,&pSvc); SysFreeString(ConnectString1); if ( FAILED (hres)) { ; } else { CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); IEnumWbemClassObject *pEnum = NULL; IWbemClassObject *pObj = NULL; // Now Update the Current field of all of the File Entries. CurrentProduct = Database; _TCHAR Query[255]; while (CurrentProduct != NULL) { CurrentHotfix = CurrentProduct->HotfixList; while (CurrentHotfix != NULL) { CurrentFile = CurrentHotfix->FileList; while (CurrentFile != NULL) { _tcscpy (Query,_T("\0")); BuildQuery(CurrentFile->InstallPath, CurrentFile->FileName, Query); _TCHAR * bstrQuery = SysAllocString(Query); _TCHAR * bstrType = SysAllocString(_T("WQL")); hres = pSvc->ExecQuery(bstrType, bstrQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum); SysFreeString (bstrQuery); SysFreeString(bstrType); if (hres == WBEM_S_NO_ERROR) { ULONG uReturned = 1; while (uReturned == 1) { hres = pEnum->Next(WBEM_INFINITE ,1,&pObj, &uReturned); if ( (SUCCEEDED (hres)) && (uReturned == 1)) { VARIANT pVal; VariantClear (&pVal); BSTR propName = SysAllocString(L"Version"); hres = pObj->Get(propName, 0L, &pVal, NULL, NULL); if (pVal.vt == VT_NULL) ; else if (pVal.vt == VT_BSTR) { TCHAR NewVal[255]; _tcscpy (NewVal, pVal.bstrVal); //_bstr_t NewVal(pVal.bstrVal,FALSE); if (! _tcscmp(CurrentFile->FileVersion, _T("\0"))) _tcscpy (CurrentFile->IsCurrent, _T("N\\A")); else { if (VerifyVersion ( CurrentFile->FileVersion, NewVal) ) { LoadString(m_hInst, IDS_YES, TempBuffer, 255); _tcscpy(CurrentFile->IsCurrent, TempBuffer); } else { LoadString(m_hInst, IDS_NO, TempBuffer, 255); _tcscpy(CurrentFile->IsCurrent,_T("\0")); } } } if (pObj) pObj->Release(); } else ; } // end while uReturned } // Done with this enumerator if (pEnum) pEnum->Release(); CurrentFile = CurrentFile->pNext; }// end while CurrentFile != NULL CurrentHotfix = CurrentHotfix->pNext; }// end while hotfix != NULL CurrentProduct = CurrentProduct->pNext; } // end while product != NULL }//end else } // end else } // end PHOTFIXLIST CListViews::GetHotfixInfo( _TCHAR * pszProductName, HKEY* hUpdateKey ) { HKEY hHotfixKey = NULL; // Handle of the hotfix key being processed. HKEY hProduct = NULL ; // Handle to the current product key HKEY hSPKey = NULL; _TCHAR szHotfixName[BUFFER_SIZE]; // Name of the current hotfix. _TCHAR szValueName[BUFFER_SIZE]; _TCHAR szSPName[BUFFER_SIZE]; PHOTFIXLIST pHotfixList = NULL; // Pointer to the head of the hotfix list. PHOTFIXLIST pCurrNode = NULL; // Used to walk the list of hotfixes PHOTFIXLIST pNewNode = NULL; // Used to create nodes to be added to the list. DWORD dwBufferSize; // Size of the product name buffer. DWORD dwValIndex; // index of current value. DWORD dwHotfixIndex = 0; BYTE *Data = NULL; DWORD dwDataSize = BUFFER_SIZE; DWORD dwValType; DWORD dwSPIndex = 0; Data = (BYTE *) malloc(BUFFER_SIZE); if (Data == NULL) return NULL; // Open the current product key if (*hUpdateKey != NULL) { RegOpenKeyEx(*hUpdateKey,pszProductName,0 , KEY_READ, &hProduct); if (hProduct != NULL) { dwHotfixIndex = 0; dwBufferSize = BUFFER_SIZE; dwSPIndex = 0; while (RegEnumKeyEx(hProduct,dwSPIndex, szSPName,&dwBufferSize, 0, NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS) { // Open the Service pack Key RegOpenKeyEx(hProduct,szSPName,0,KEY_READ,&hSPKey); if (hSPKey != NULL) { // Enumerate the Service Pack key to get the hotfix keys. dwBufferSize = BUFFER_SIZE; dwHotfixIndex = 0; while (RegEnumKeyEx(hSPKey,dwHotfixIndex, szHotfixName, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS) { // now create a new node pNewNode = (PHOTFIXLIST) malloc (sizeof(HOTFIXLIST)); pNewNode->pNext = NULL; pNewNode->FileList = NULL; _tcscpy(pNewNode->HotfixName,szHotfixName); _tcscpy(pNewNode->ServicePack,szSPName); _tcscpy(pNewNode->Uninstall,_T("\0")); // Open the Hotfix Key RegOpenKeyEx(hSPKey,szHotfixName, 0, KEY_READ,&hHotfixKey); if (hHotfixKey != NULL) { // Now enumerate the values of the current hotfix. dwValIndex = 0; dwBufferSize =BUFFER_SIZE; dwDataSize = BUFFER_SIZE; while (RegEnumValue(hHotfixKey,dwValIndex, szValueName,&dwBufferSize, 0,&dwValType, Data, &dwDataSize) != ERROR_NO_MORE_ITEMS) { // Fill in the hotfix data members. _tcslwr(szValueName); if (!_tcscmp(szValueName,_T("description"))) _tcscpy(pNewNode->Description,(_TCHAR *) Data); if (!_tcscmp(szValueName,_T("installeddate"))) _tcscpy(pNewNode->InstalledDate,(_TCHAR *) Data); if (!_tcscmp(szValueName,_T("type"))) _tcscpy(pNewNode->Type,(_TCHAR*) Data); if (!_tcscmp(szValueName,_T("installedby"))) _tcscpy(pNewNode->InstalledBy , (_TCHAR*) Data); if (!_tcscmp(szValueName,_T("uninstallcommand"))) _tcscpy(pNewNode->Uninstall, (_TCHAR*)Data); ++ dwValIndex; _tcscpy (szValueName, _T("\0")); ZeroMemory(Data,BUFFER_SIZE); dwValType = 0; dwBufferSize =BUFFER_SIZE; dwDataSize = BUFFER_SIZE; } // Get the file list for the current hotfix. pNewNode->FileList = GetFileInfo(&hHotfixKey); //insert the new node at the end of the hotfix list. pCurrNode = pHotfixList; if (pCurrNode == NULL) { pHotfixList = pNewNode; pHotfixList->pPrev = NULL; pHotfixList->pNext = NULL; } else { pCurrNode = pHotfixList; while (pCurrNode->pNext != NULL) pCurrNode = pCurrNode->pNext; pCurrNode->pNext = pNewNode; pNewNode->pPrev = pCurrNode; pNewNode->pNext = NULL; } // Close the current Hotfix Key RegCloseKey(hHotfixKey); // Clear the strings. _tcscpy(szHotfixName,_T("\0")); // increment the current index ++dwHotfixIndex; dwBufferSize = BUFFER_SIZE; } } RegCloseKey(hSPKey); _tcscpy (szSPName,_T("\0")); dwBufferSize = BUFFER_SIZE; dwSPIndex++; } }// end enum SP keys. // Close all open keys RegCloseKey(hProduct); } if (Data != NULL) free (Data); } return pHotfixList; } PFILELIST CListViews::GetFileInfo(HKEY* hHotfixKey) { PFILELIST pFileList = NULL; // Pointer to the head of the file list. // _TCHAR szFilePath; // Path to the files subkey. PFILELIST pNewNode = NULL; PFILELIST pCurrNode = NULL;; BYTE * Data; DWORD dwBufferSize = BUFFER_SIZE; DWORD dwDataSize = BUFFER_SIZE; DWORD dwFileIndex = 0; DWORD dwPrimeIndex = 0; DWORD dwValType = 0; HKEY hPrimaryFile; HKEY hFileKey; _TCHAR szFileSubKey[BUFFER_SIZE]; _TCHAR szValueName[BUFFER_SIZE]; Data = (BYTE *) malloc(BUFFER_SIZE); ZeroMemory(Data,BUFFER_SIZE); // Open the files subkey of the current hotfix if (RegOpenKeyEx(*hHotfixKey, _T("FileList"),0,KEY_READ,&hPrimaryFile) != ERROR_SUCCESS) { return NULL; } _tcscpy(szValueName,_T("\0")); while (RegEnumKeyEx(hPrimaryFile,dwPrimeIndex,szFileSubKey, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS) { // open the subfile key RegOpenKeyEx(hPrimaryFile,szFileSubKey,0,KEY_READ,&hFileKey); dwFileIndex = 0; // Enumerate the file(x) subkeys of the file subkey dwDataSize = BUFFER_SIZE; dwBufferSize = BUFFER_SIZE; pNewNode = (PFILELIST) malloc (sizeof(FILELIST)); pNewNode->pNext = NULL; pNewNode->pPrev = NULL; _tcscpy (pNewNode->IsCurrent,_T("\0")); _tcscpy(pNewNode->FileDate,_T("\0")); while (RegEnumValue(hFileKey,dwFileIndex,szValueName,&dwBufferSize,0,&dwValType,Data,&dwDataSize) != ERROR_NO_MORE_ITEMS) { _tcslwr(szValueName); // now find out which value we have and insert it into the node if (! _tcscmp(szValueName,_T("filename"))) { _tcscpy(pNewNode->FileName,(_TCHAR *) Data); } if (! _tcscmp(szValueName,_T("version"))) { _tcscpy(pNewNode->FileVersion,(_TCHAR*)Data); } if (!_tcscmp(szValueName,_T("builddate"))) { _tcscpy(pNewNode->FileDate,(_TCHAR*) Data); } if (! _tcscmp(szValueName, _T("location"))) { _tcscpy(pNewNode->InstallPath, (_TCHAR*) Data); } dwFileIndex ++; _tcscpy(szValueName,_T("\0")); ZeroMemory(Data,BUFFER_SIZE); dwValType = 0; dwBufferSize = BUFFER_SIZE; dwDataSize = BUFFER_SIZE; } RegCloseKey(hFileKey); // add the current node to the list if not stored in dll cache _TCHAR TempString[255]; _tcscpy (TempString, pNewNode->InstallPath); _tcslwr(TempString); if ( (_tcsstr (TempString, _T("dllcache")) == NULL ) && (_tcsstr (TempString, _T("driver cache") )== NULL)) { pCurrNode = pFileList; if (pNewNode != NULL) { if (pFileList == NULL) { pFileList = pNewNode; } else { while (pCurrNode->pNext != NULL) pCurrNode = pCurrNode->pNext; pCurrNode->pNext = pNewNode; pNewNode->pPrev = pCurrNode; } } } else // otherwise free the node. free (pNewNode); ++dwPrimeIndex; } // end enum of primary file key RegCloseKey(hPrimaryFile); if (Data != NULL) free (Data); return pFileList; } _TCHAR * CListViews::GetCurrentHotfix() { return m_CurrentHotfix; } void CListViews::SetViewMode(DWORD ViewType) { m_CurrentView = ViewType; _tcscpy (m_CurrentHotfix,_T("\0")); EnableWindow(m_UninstButton,FALSE); EnableWindow(m_WebButton,FALSE); switch (ViewType) { case VIEW_BY_FILE: if (! _tcscmp(m_ProductName,_T("\0"))) m_CurrentView = VIEW_ALL_FILE; else m_CurrentView = VIEW_BY_FILE; break; case VIEW_BY_HOTFIX: if (! _tcscmp(m_ProductName,_T("\0"))) m_CurrentView =VIEW_ALL_HOTFIX; else m_CurrentView = VIEW_BY_HOTFIX; break; } AddItemsTop(); AddItemsBottom(); } void CListViews::SetProductName(_TCHAR * NewName) { _tcscpy (m_ProductName,NewName); _tcscpy(m_ProductName, NewName); EnableWindow(m_WebButton, FALSE); EnableWindow(m_UninstButton,FALSE); _tcscpy(m_CurrentHotfix, _T("\0")); if (_tcscmp(NewName, _T("\0"))) { switch (m_CurrentView) { case VIEW_ALL_FILE: m_CurrentView = VIEW_BY_FILE; break; case VIEW_ALL_HOTFIX: m_CurrentView = VIEW_BY_HOTFIX; break; } } if (!_tcscmp(NewName, _T("\0"))) { switch (m_CurrentView) { case VIEW_BY_FILE: m_CurrentView = VIEW_ALL_FILE; break; case VIEW_BY_HOTFIX: m_CurrentView = VIEW_ALL_HOTFIX; break; default: m_CurrentView = VIEW_ALL_HOTFIX; } _tcscpy(m_ProductName,_T("\0")); _tcscpy(m_CurrentHotfix,_T("\0")); } AddItemsTop(); AddItemsBottom(); } BOOL CListViews::FreeFileList(PFILELIST CurrentFile) { while (CurrentFile->pNext->pNext != NULL) CurrentFile = CurrentFile->pNext; //Remove the file list while ( (CurrentFile->pPrev != NULL) && (CurrentFile->pNext != NULL) ) { free ( CurrentFile->pNext ); CurrentFile = CurrentFile->pPrev ; } if (CurrentFile != NULL) free (CurrentFile); CurrentFile = NULL; return TRUE; } BOOL CListViews::FreeHotfixList (PHOTFIXLIST CurrentHotfix) { PFILELIST CurrentFile; while (CurrentHotfix->pNext != NULL) CurrentHotfix = CurrentHotfix->pNext; if (CurrentHotfix->pPrev != NULL) CurrentHotfix = CurrentHotfix->pPrev; //Remove the Hotfix list while ( (CurrentHotfix->pPrev != NULL) && (CurrentHotfix->pNext != NULL) ) { CurrentFile = CurrentHotfix->pNext->FileList ; FreeFileList (CurrentFile); free ( CurrentHotfix->pNext ); CurrentHotfix = CurrentHotfix->pPrev ; } if (CurrentHotfix != NULL) free (CurrentHotfix); return TRUE; } BOOL CListViews::FreeDatabase() { PPRODUCT CurrentProduct = DataBase; PHOTFIXLIST CurrentHotfix; PFILELIST CurrentFile; while (CurrentProduct->pNext->pNext != NULL) CurrentProduct = CurrentProduct->pNext; while (CurrentProduct->pPrev != NULL) { CurrentHotfix = CurrentProduct->HotfixList; FreeHotfixList(CurrentHotfix); CurrentProduct = CurrentProduct->pPrev ; } if (CurrentProduct != NULL) free(CurrentProduct); DataBase = NULL; return TRUE; } BOOL CListViews::Uninstall() { char temp[255]; PPRODUCT pProduct = NULL; PHOTFIXLIST pHotfix = NULL; pProduct = DataBase; BOOL Done = FALSE; if (_tcscmp (m_ProductName,_T("\0"))) { while ( (!Done) && (pProduct != NULL)) { if (!_tcscmp(pProduct->ProductName, m_ProductName)) Done = TRUE; else pProduct = pProduct->pNext; } } else { while ( (!Done) && (pProduct != NULL)) { if (!_tcscmp(pProduct->ProductName, CurrentProductName)) Done = TRUE; else pProduct = pProduct->pNext; } } if (pProduct != NULL) pHotfix = pProduct->HotfixList; if (pHotfix != NULL) { Done = FALSE; while( (!Done) && (pHotfix != NULL) ) { if ( ! _tcscmp(pHotfix->HotfixName,m_CurrentHotfix)) Done = TRUE; else pHotfix = pHotfix->pNext; } if (pHotfix != NULL) { if (_tcscmp(pHotfix->Uninstall, _T("\0"))) { _TCHAR TempString[255]; _TCHAR TempString2[255]; LoadString(m_hInst,IDS_UNINSTAL_WRN,TempString,255); _tcscat (TempString, pHotfix->HotfixName); LoadString(m_hInst,IDS_UNINSTAL_WRN_TITLE,TempString2,255); if (::MessageBox(NULL,TempString,TempString2, MB_OKCANCEL) != IDCANCEL) { wcstombs(temp,pHotfix->Uninstall,255); WinExec( (char*)temp, SW_SHOWNORMAL); // Free the database FreeDatabase(); DataBase = NULL; BuildDatabase( m_ComputerName); } } } } return TRUE; } void InitializeOfn(OPENFILENAME *ofn) { static _TCHAR szFilter[] = _T("Text (Comma Delimited) (*.csv)\0*.csv\0\0") ; ofn->lStructSize = sizeof (OPENFILENAME); ofn->hwndOwner = NULL; ofn->hInstance = NULL; ofn->lpstrFilter = szFilter; ofn->lpstrCustomFilter = NULL; ofn->nMaxCustFilter = 0; ofn->lpstrFile = NULL; ofn->nMaxFile = MAX_PATH; ofn->lpstrFileTitle = NULL; ofn->Flags = OFN_OVERWRITEPROMPT; ofn->nFileOffset = 0; ofn->nFileExtension = 0; ofn->lpstrDefExt = _T("csv"); ofn->lCustData = 0L; ofn->lpfnHook = NULL; ofn->lpTemplateName = NULL; } void CListViews::SaveToCSV() { PPRODUCT pProduct = NULL; PHOTFIXLIST pHotfix = NULL; PFILELIST pFileList = NULL; _TCHAR *Buffer; DWORD LineLength = 0; HANDLE hFile = NULL; DWORD BytesWritten = 0; DWORD LineSize = 0; char *Buffer2; static OPENFILENAME ofn; _TCHAR FileName[MAX_PATH]; _tcscpy (FileName,_T("\0")); InitializeOfn (&ofn); ofn.lpstrFile = FileName; if ( !GetSaveFileName(&ofn) ) { return; } // open the file hFile = CreateFile( FileName, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if ( hFile == INVALID_HANDLE_VALUE) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); // Process any inserts in lpMsgBuf. // ... // Display the string. // MessageBox( NULL, (LPCTSTR)lpMsgBuf,_T(" Error"), MB_OK | MB_ICONINFORMATION ); // Free the buffer. LocalFree( lpMsgBuf ); return; } // Store Headers Buffer = (_TCHAR *) malloc (2000); Buffer2 = (char*) malloc(2000); LoadString(m_hInst,IDS_CSV_HEADER,Buffer,1000); //_stprintf(Buffer, _T("Product,Service Pack,Article,InstalledBy,InstalledDate,FileName,FileVersion,FileDate,InstallPath,Current\r")); wcstombs(Buffer2,Buffer, _msize(Buffer2) ); WriteFile(hFile,Buffer2, strlen(Buffer2), &BytesWritten, NULL); if (Buffer) free (Buffer); if (Buffer2) free (Buffer2); Buffer = NULL; Buffer2 = NULL; // Run through the Data base and write the info to the file. pProduct = DataBase; while (pProduct != NULL) { pHotfix = pProduct->HotfixList; while (pHotfix != NULL) { pFileList = pHotfix->FileList; while (pFileList != NULL) { // Build the CSV output string // Product,Article,Description, ServicePack, By, Date, Type, FileName, Version, Date,Current,InstallPath // Add up the string lengths and allocata a large enough buffer. LineLength = _tcslen(pProduct->ProductName) + _tcslen(pHotfix->ServicePack)+ _tcslen(pHotfix->HotfixName) + _tcslen(pHotfix->Description )+ _tcslen(pHotfix->InstalledBy ) + _tcslen(pHotfix->InstalledDate) + _tcslen(pHotfix->Type) + _tcslen(pFileList->FileName ) + _tcslen(pFileList->FileVersion ) + _tcslen(pFileList->FileDate ) + _tcslen(pFileList->InstallPath )+ _tcslen(pFileList->IsCurrent ); Buffer = (_TCHAR *) malloc ( LineLength * sizeof (_TCHAR ) *2) ; Buffer2 = (char *) malloc (LineLength *2); //ZeroMemory(Buffer, (LineLength * sizeof (_TCHAR)) +2); _tcscpy (Buffer,_T("\0")); strcpy(Buffer2,"\0"); if (!Buffer) MessageBox (NULL,_T("NO Memory"),NULL, MB_OK); else { _stprintf(Buffer,_T("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\r\0\0"),pProduct->ProductName, pHotfix->ServicePack,pHotfix->HotfixName,pHotfix->Description ,pHotfix->InstalledBy, pHotfix->InstalledDate, pHotfix->Type,pFileList->FileName,pFileList->FileVersion,pFileList->FileDate , pFileList->InstallPath,pFileList->IsCurrent); // Write the line to the file LineSize = 0; LineSize = wcstombs(Buffer2,Buffer, _msize (Buffer2) ); strcat(Buffer2,"\0"); WriteFile(hFile, Buffer2, LineSize, &BytesWritten, NULL); } // Free the buffer and zero the line length for next pass. if (Buffer) { free (Buffer); free (Buffer2); } Buffer = NULL; Buffer2 = NULL; LineLength = 0; pFileList = pFileList->pNext; } pHotfix = pHotfix->pNext; } pProduct = pProduct->pNext; } CloseHandle(hFile); } DWORD CListViews::GetState() { DWORD dwStatus =0; PPRODUCT CurrentProduct; PHOTFIXLIST CurrentHotfix; BOOL Done = FALSE;; switch (m_CurrentView) { case VIEW_ALL_FILE: case VIEW_BY_FILE: dwStatus |= STATE_VIEW_FILE; break; case VIEW_ALL_HOTFIX: case VIEW_BY_HOTFIX: dwStatus |= STATE_VIEW_HOTFIX; break; } // Do we have a database. if (DataBase == NULL) return dwStatus; // Does the database contain any data... // A case can arise if a hotfix is installed and then uninstalled where the Registry keys // for the Product and Service Pack are not removed. We need to have at least 1 hotfix list. CurrentProduct = DataBase; while ( (CurrentProduct != NULL) && (!Done)) { if (CurrentProduct ->HotfixList != NULL) Done = TRUE; CurrentProduct = CurrentProduct->pNext; } if (!Done) { //dwStatus = 0; return dwStatus; } else { // We do have data in the database so we can enable the Export list and Print options. dwStatus |= DATA_TO_SAVE; dwStatus |= OK_TO_PRINT; } // Do we have a hotfix selected if (_tcscmp(m_CurrentHotfix,_T("\0"))) dwStatus |= HOTFIX_SELECTED; else { // If we don't have a selected hotfix we cant view the web or uninstall so // Just return the current status return dwStatus; } // Now we need to see if we have an uninstall string for the current hotfix CurrentProduct = DataBase; // Find the selected product Done = FALSE; while ( (CurrentProduct != NULL) && (!Done)) { if (!_tcscmp(CurrentProduct->ProductName ,m_ProductName)) { // Find the selected hotfix CurrentHotfix = CurrentProduct->HotfixList; while ((CurrentHotfix != NULL) && (!Done)) { if (! _tcscmp (CurrentHotfix->HotfixName, m_CurrentHotfix)) { // Now verify the uninstall string exists if (_tcscmp(CurrentHotfix->Uninstall, _T("\0"))) { // Now verify the directory still exists _TCHAR TempString[255]; _tcscpy (TempString,CurrentHotfix->Uninstall); PathRemoveArgs(TempString); if ( PathFileExists( TempString )) { // Yes it does we can enable uninstall dwStatus |=UNINSTALL_OK; } } Done = TRUE; } CurrentHotfix = CurrentHotfix->pNext; } } CurrentProduct = CurrentProduct->pNext; } return dwStatus; } _TCHAR * BuildDocument() { // _TCHAR Document; return NULL; } BOOL CALLBACK AbortProc(HDC hPrinterDC, int iCode) { MSG msg; while (!bUserAbort && PeekMessage (&msg, NULL,0,0,PM_REMOVE)) { if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg)) { TranslateMessage (&msg); DispatchMessage (&msg); } } return !bUserAbort; } BOOL CALLBACK PrintDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG : EnableMenuItem (GetSystemMenu (hDlg,FALSE), SC_CLOSE, MF_GRAYED); return TRUE; case WM_COMMAND: bUserAbort = TRUE; EnableWindow (GetParent (hDlg), TRUE); DestroyWindow (hDlg); hDlgPrint = NULL; return TRUE; } return FALSE; } BOOL JustifyString( _TCHAR* String, int FieldLength, BOOL Left) { _TCHAR TempString[255]; int i= 0; int NumSpaces = 0; _TCHAR Message[100]; _TCHAR *src, *dest; if (String == NULL) { return FALSE; } if (Left) { // String leading spaces. src = String; dest = TempString; while (*src == _T(' ')) ++src; while (*src != _T('\0')) { *dest = *src; ++src; ++dest; } *dest = _T('\0'); ++dest; *dest = _T('\0'); NumSpaces = (FieldLength - _tcslen(TempString) ); _stprintf(Message,_T("FieldSize: %d, String Length: %d"),FieldLength, _tcslen(TempString)); // MessageBox(NULL,Message,_T("Justify"),MB_OK); while (NumSpaces >0) { _tcscat(TempString,_T(" ")); --NumSpaces; } _tcscpy (String, TempString); _stprintf(Message,_T("NewString Length: %d"),_tcslen(String)); // MessageBox(NULL,Message,_T("New String Length"),MB_OK); } else { _tcscpy(TempString,_T("\0")); NumSpaces = FieldLength - _tcslen(String); if (NumSpaces > 0 ) { for (i = 0 ; i < NumSpaces;i++) TempString[i] = _T(' '); TempString[i] = _T('\0'); _tcscat(TempString,String); _tcscpy(String,TempString); } } return TRUE; } void GetFont ( int PointSize, BOOL Bold, BOOL Underlined, LOGFONT * lf, HDC hDC) { POINT pt; lf->lfHeight = PointSize * 10; pt.y = GetDeviceCaps(hDC, LOGPIXELSY) * lf->lfHeight; pt.y /= 720; // 72 points/inch, 10 decipoints/point DPtoLP(hDC, &pt, 1); POINT ptOrg = { 0, 0 }; DPtoLP(hDC, &ptOrg, 1); lf->lfHeight = -abs(pt.y - ptOrg.y); if (Underlined) lf->lfUnderline = TRUE; else lf->lfUnderline = FALSE; if (Bold) lf->lfWeight = FW_BOLD; else lf->lfWeight = FW_NORMAL; } void NewPage (HDC hDC, _TCHAR *Header1, _TCHAR * Header2, DWORD * CurrentLine, LOGFONT * lf) { TEXTMETRIC tm; SIZE size; DWORD xStart; DWORD yChar; RECT rect; rect.left = (LONG) (0 + GetDeviceCaps(hDC, LOGPIXELSX) * 0.5); rect.right = (LONG) (GetDeviceCaps(hDC, PHYSICALWIDTH) -(1+ (GetDeviceCaps(hDC, LOGPIXELSX) / 2))); rect.top = (LONG) (1 + GetDeviceCaps(hDC, LOGPIXELSY) * 0.5); rect.bottom = (LONG) (GetDeviceCaps(hDC, PHYSICALHEIGHT) - GetDeviceCaps(hDC, LOGPIXELSX) * 0.5); if (StartPage(hDC) > 0) { *CurrentLine = 1; GetFont (12,TRUE,TRUE,lf,hDC); SelectObject(hDC, CreateFontIndirect(lf)); GetTextMetrics(hDC,&tm); yChar = tm.tmHeight + tm.tmExternalLeading ; GetTextExtentPoint32(hDC, Header1,_tcslen(Header1),&size); xStart = (rect.right - rect.left)/2 - size.cx/2 ; TextOut (hDC, xStart,(*CurrentLine)* yChar ,Header1, _tcslen(Header1) ); GetFont (10,FALSE, FALSE, lf, hDC); SelectObject(hDC, CreateFontIndirect (lf)); GetTextMetrics (hDC, &tm); yChar = tm.tmHeight + tm.tmExternalLeading ; xStart = rect.right - ((_tcslen(Header2) +2) * tm.tmAveCharWidth); TextOut(hDC, xStart,(*CurrentLine) * yChar, Header2, _tcslen(Header2)); (*CurrentLine) += 4; } } void CListViews::PrintReport() { static DOCINFO di = {sizeof (DOCINFO) } ; static PRINTDLG pd; BOOL bSuccess; int yChar, iCharsPerLine, iLinesPerPage; _TCHAR Header1[255]; _TCHAR Header2[255]; TEXTMETRIC tm; _TCHAR Line [255]; PPRODUCT CurrentProduct; PHOTFIXLIST CurrentHotfix; PFILELIST CurrentFile; DWORD CurrentLine = 0; DWORD yStart = 0; _TCHAR TempBuffer[255]; RECT rect; SIZE size; _TCHAR * src; DWORD xStart; static LOGFONT lf; SYSTEMTIME systime; BOOL Done = FALSE; _TCHAR SystemDate[255]; _TCHAR SystemTime[255]; _TCHAR TempBuffer1[255]; _TCHAR TempBuffer2[255]; // invoke Print common dialog box GetLocalTime(&systime); GetDateFormatW (LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,NULL, SystemDate,255); GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &systime,NULL,SystemTime,255); CurrentProduct = DataBase; pd.lStructSize = sizeof (PRINTDLG); pd.hwndOwner = TopList; //m_hWnd; pd.hDevMode = NULL; pd.hDevNames= NULL; pd.hDC= NULL; pd.Flags = PD_ALLPAGES | PD_COLLATE | PD_RETURNDC | PD_NOSELECTION ; pd.nFromPage = 0; pd.nToPage = 0; pd.nMinPage = 0; pd.nMaxPage = 0; pd.nCopies = 1; pd.hInstance = NULL; pd.lCustData = 0L; pd.lpfnPrintHook = NULL; pd.lpfnSetupHook = NULL; pd.lpPrintTemplateName = NULL; pd.lpSetupTemplateName = NULL; pd.hPrintTemplate = NULL; pd.hSetupTemplate = NULL; if (!PrintDlg (&pd) ) return; //TRUE; else { // Setup the printer dimensions. rect.left = (LONG) (0 + GetDeviceCaps(pd.hDC, LOGPIXELSX) * 0.5); rect.right = (LONG) (GetDeviceCaps(pd.hDC, PHYSICALWIDTH) - GetDeviceCaps(pd.hDC, LOGPIXELSX) * 0.5); rect.top = (LONG) (1 + GetDeviceCaps(pd.hDC, LOGPIXELSY) * 0.5); rect.bottom = (LONG) ( GetDeviceCaps(pd.hDC, PHYSICALHEIGHT) - GetDeviceCaps(pd.hDC, LOGPIXELSX) * 0.5); rect.bottom -= 100; bSuccess = TRUE; bUserAbort = TRUE; hDlgPrint = CreateDialog(m_hInst, _T("PrintDlgBox"), TopList, PrintDlgProc ); di.lpszDocName = _T("Hotfix Manager"); SetAbortProc(pd.hDC, AbortProc); LOGFONT logFont; memset(&logFont, 0, sizeof(LOGFONT)); logFont.lfCharSet = DEFAULT_CHARSET; _tcscpy(logFont.lfFaceName, _T("Dlg Shell Font")); LoadString(m_hInst, IDS_UPDATE_REPORT, TempBuffer, 255); _stprintf(Header1,_T("%s %s"), TempBuffer,m_ComputerName); _stprintf(Header2, _T("%s %s"),SystemDate,SystemTime); StartDoc(pd.hDC,&di); _tcscpy (Line,_T("\0")); NewPage (pd.hDC, Header1,Header2, &CurrentLine, &logFont); GetTextMetrics(pd.hDC,&tm); yChar = tm.tmHeight + tm.tmExternalLeading ; iCharsPerLine = GetDeviceCaps (pd.hDC, HORZRES) / tm.tmAveCharWidth ; iLinesPerPage = GetDeviceCaps (pd.hDC, VERTRES) / yChar ; _tcscpy (Line,_T("\0")); xStart = rect.left; while ( (CurrentProduct != NULL) && (!Done)) { _tcscpy (Line,_T("\0")); LoadString(m_hInst,IDS_PRODUCT_NAME, TempBuffer,255); logFont.lfWeight = FW_BOLD; SelectObject(pd.hDC,CreateFontIndirect (&logFont)); GetTextMetrics (pd.hDC, &tm); _stprintf (Line, _T("%s: "), TempBuffer); yStart = CurrentLine * yChar; if (yStart >= (UINT) rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } TextOut (pd.hDC, xStart,yStart ,Line, _tcslen(Line) ); xStart = rect.left + ((_tcslen(Line) + 4 )* tm.tmAveCharWidth); logFont.lfWeight = FW_NORMAL; SelectObject(pd.hDC,CreateFontIndirect (&logFont)); GetTextMetrics (pd.hDC, &tm); _tcscpy (Line, CurrentProduct->ProductName); TextOut(pd.hDC, xStart, yStart , Line, _tcslen(Line) ); CurrentLine ++; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } xStart = rect.left; CurrentHotfix = CurrentProduct->HotfixList; while ( (CurrentHotfix != NULL ) && (!Done)) { _stprintf (Line, _T("%s \t%s"),CurrentHotfix->HotfixName,CurrentHotfix->Description ); TabbedTextOut (pd.hDC, xStart,yStart ,Line, _tcslen(Line),0,NULL,0 ); ++CurrentLine; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } LoadString (m_hInst,IDS_SERVICE_PACK, TempBuffer, 255); LoadString (m_hInst,IDS_INSTALL_DATE, TempBuffer1, 255); LoadString (m_hInst,IDS_INSTALLED_BY, TempBuffer2, 255); _stprintf(Line, _T("\t\t%s: %s \t%s: %s \t%s: %s"), TempBuffer, CurrentHotfix->ServicePack, TempBuffer1, CurrentHotfix->InstalledDate, TempBuffer2, CurrentHotfix->InstalledBy); // _stprintf (Line, _T("\t\tService Pack: %s\tInstall Date: %s\tInstalled By %s"), // CurrentHotfix->ServicePack,CurrentHotfix->InstalledDate, CurrentHotfix->InstalledBy); TabbedTextOut (pd.hDC, xStart,yStart ,Line, _tcslen(Line),0,NULL,0 ); CurrentLine +=2; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } CurrentFile = CurrentHotfix->FileList ; if (CurrentFile == NULL) { _tcscpy (Line, _T("\0")); LoadString(m_hInst,IDS_NO_FILES,Line,255); TextOut (pd.hDC, xStart,yStart ,Line, _tcslen(Line) ); CurrentLine += 2; if (yStart >= (UINT) rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } } else { logFont.lfUnderline = TRUE; logFont.lfWeight = FW_BOLD; SelectObject(pd.hDC, CreateFontIndirect (&logFont)); _tcscpy (Line, _T("\0")); LoadString (m_hInst, IDS_FILE,TempBuffer,255); JustifyString(TempBuffer,FILENAME_FIELD_WIDTH,TRUE); TextOut( pd.hDC, xStart,yStart ,TempBuffer, _tcslen(TempBuffer) ); LoadString (m_hInst, IDS_FILEDATE,TempBuffer,255); JustifyString(TempBuffer,DATE_FIELD_WIDTH,TRUE); TextOut( pd.hDC, xStart + 29 * tm.tmAveCharWidth ,yStart ,TempBuffer, _tcslen(TempBuffer) ); LoadString (m_hInst, IDS_FILEVERSION,TempBuffer,255); JustifyString(TempBuffer,VERSION_FIELD_WIDTH,TRUE); TextOut( pd.hDC, xStart + 45 * tm.tmAveCharWidth ,yStart ,TempBuffer, _tcslen(TempBuffer) ); LoadString (m_hInst, IDS_FILECURRENT,TempBuffer,255); JustifyString(TempBuffer,CURRENT_FIELD_WIDTH,TRUE); TextOut( pd.hDC, xStart + 61* tm.tmAveCharWidth,yStart ,TempBuffer, _tcslen(TempBuffer) ); LoadString (m_hInst, IDS_FILEPATH,TempBuffer,255); JustifyString(TempBuffer,PATH_FIELD_WIDTH,TRUE); TextOut( pd.hDC, xStart+72 * tm.tmAveCharWidth ,yStart ,TempBuffer, _tcslen(TempBuffer) ); ++ CurrentLine; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } } while ( (CurrentFile != NULL) && (!Done) ) { logFont.lfWeight = FW_NORMAL; logFont.lfUnderline = FALSE; SelectObject(pd.hDC, CreateFontIndirect (&logFont)); _tcscpy (Line, _T("\0")); _tcscpy (Line, CurrentFile->FileName); // JustifyString(Line,40, TRUE); TextOut (pd.hDC, xStart,yStart ,Line, _tcslen(Line) ); //_tcscat (Line,TempBuffer); _tcscpy (Line, CurrentFile->FileDate); // JustifyString(Line,20, TRUE); TextOut (pd.hDC, xStart + 29 * tm.tmAveCharWidth,yStart ,Line, _tcslen(Line) ); _tcscpy (Line, CurrentFile->FileVersion ); // JustifyString(Line,18, TRUE); TextOut (pd.hDC, xStart + 45 * tm.tmAveCharWidth,yStart ,Line, _tcslen(Line) ); _tcscpy (Line, CurrentFile->IsCurrent); // JustifyString(Line,12, TRUE); TextOut (pd.hDC, xStart + 61 * tm.tmAveCharWidth,yStart ,Line, _tcslen(Line) ); _tcscpy (Line,CurrentFile->InstallPath); TextOut (pd.hDC, xStart + 72 * tm.tmAveCharWidth,yStart ,Line, _tcslen(Line) ); ++CurrentLine; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { // MessageBox (NULL,_T("Hit Page Break Code"),NULL,MB_OK); EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } CurrentFile = CurrentFile->pNext; if (!bUserAbort) Done = TRUE; } // End While Current File ++CurrentLine; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } CurrentHotfix = CurrentHotfix->pNext; if (!bUserAbort) Done = TRUE; } ++CurrentLine; yStart = CurrentLine * yChar; if (yStart >= (UINT)rect.bottom) { EndPage(pd.hDC); NewPage(pd.hDC, Header1,Header2, &CurrentLine, &logFont); yStart = CurrentLine * yChar; } CurrentProduct = CurrentProduct->pNext; if (!bUserAbort) Done = TRUE; } if (EndPage(pd.hDC) > 0) EndDoc(pd.hDC); DeleteDC(pd.hDC); DestroyWindow(hDlgPrint); } return; //FALSE; } int CALLBACK CListViews::CompareFunc (LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { int Result = -1; int SubItemIndex = (INT) lParamSort; _TCHAR String1[1000]; _TCHAR String2 [1000]; ListView_GetItemText( TopList, lParam1, SubItemIndex, String1, 1000); ListView_GetItemText( TopList, lParam2, SubItemIndex, String2, 1000); if (! (String1 && String2) ) return 1; if (m_SortOrder) // Sort Acending { Result = _tcscmp(String1,String2); } else // Sort Decending { Result = -_tcscmp(String1,String2); } if (Result == 0) Result = -1; return Result; }