mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1025 lines
24 KiB
1025 lines
24 KiB
#include "pch.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "resource.h"
|
|
#include "infprod.h"
|
|
#include "addopt.h"
|
|
#include "setupapi.h"
|
|
|
|
|
|
|
|
BOOL CAddListView::OnClick()
|
|
{
|
|
BOOL fEnable;
|
|
CAddOptionDialog* pParent = GetParentObject(CAddOptionDialog, m_list);
|
|
int sel = GetCurrentSelection();
|
|
fEnable = (sel != -1);
|
|
|
|
if (sel != -1)
|
|
{
|
|
// Get the item data and see if it is the message string
|
|
LV_ITEM lvi;
|
|
lvi.mask = LVIF_PARAM;
|
|
lvi.iSubItem = 0;
|
|
lvi.iItem = sel;
|
|
ListView_GetItem(*this, &lvi);
|
|
if (lvi.lParam == -1)
|
|
return FALSE;
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(*pParent, IDOK), fEnable);
|
|
return fEnable;
|
|
}
|
|
|
|
BOOL CAddListView::OnDoubleClick()
|
|
{
|
|
CAddOptionDialog* pParent = GetParentObject(CAddOptionDialog, m_list);
|
|
|
|
ASSERT(pParent != NULL);
|
|
|
|
if (OnClick())
|
|
{
|
|
pParent->OnOk();
|
|
}
|
|
return CListView::OnDoubleClick();
|
|
}
|
|
|
|
CAddOptionDialog::CAddOptionDialog(OptionTypes eType, NCP* pNcp, CPtrList* pList)
|
|
{
|
|
m_eType = eType;
|
|
m_tid = 0;
|
|
m_mainThread = 0;
|
|
m_hEvent = 0;
|
|
m_nImage = 0;
|
|
m_hImage = 0;
|
|
m_bWaitCursor = FALSE;
|
|
m_hThread = 0;
|
|
m_pInfProduct = 0;
|
|
m_pNcp = pNcp;
|
|
|
|
m_bHaveDisk = FALSE;
|
|
m_hHaveDiskThread = 0;
|
|
|
|
if (pList == NULL)
|
|
{
|
|
m_optionList = new CPtrList;
|
|
m_bDeleteList = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_optionList = pList;
|
|
m_bDeleteList = FALSE;
|
|
}
|
|
}
|
|
|
|
CAddOptionDialog::~CAddOptionDialog()
|
|
{
|
|
}
|
|
|
|
BOOL CAddOptionDialog::OnInitDialog()
|
|
{
|
|
HWND hDlg = *this;
|
|
|
|
// Attach list view and set images
|
|
m_list.Create(hDlg, IDC_LISTVIEW, LVS_SHOWSELALWAYS);
|
|
m_hImage = ImageList_LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_IMAGELIST), 16, 0,RGB(0,128,128));
|
|
ListView_SetImageList(m_list, m_hImage, LVSIL_SMALL);
|
|
|
|
// Changes the style of the static control so it displays
|
|
HWND hLine = GetDlgItem(hDlg, IDC_STATIC_LINE);
|
|
SetWindowLong(hLine, GWL_EXSTYLE, WS_EX_STATICEDGE |GetWindowLong(hLine, GWL_EXSTYLE));
|
|
SetWindowPos(hLine, 0, 0,0,0,0, SWP_FRAMECHANGED|SWP_NOMOVE|
|
|
SWP_NOZORDER|SWP_NOSIZE|SWP_NOACTIVATE);
|
|
|
|
RECT rect;
|
|
|
|
if (m_bDeleteList == FALSE)
|
|
{
|
|
CenterDialogToScreen(hDlg); // wizard mode
|
|
}
|
|
else
|
|
{
|
|
CascadeDialogToWindow( hDlg, DialogParent(), FALSE );
|
|
}
|
|
|
|
// Load correct icon for add option, service by default
|
|
UINT nIcon = IDI_CLIENT;
|
|
UINT nDialogTitle = IDS_SELECT_SERVICE;
|
|
UINT nString = IDS_SELECT_OPTION_SERVICE;
|
|
m_nImage = ILI_CLIENT;
|
|
|
|
if (m_eType == ADAPTER)
|
|
{
|
|
m_nImage = ILI_NETCARD;
|
|
nIcon = IDI_ADAPTER;
|
|
nDialogTitle = IDS_SELECT_ADAPTER;
|
|
nString = IDS_SELECT_OPTION_ADAPTER;
|
|
}
|
|
else if (m_eType == PROTOCOL)
|
|
{
|
|
m_nImage = ILI_PROTOCOL;
|
|
nIcon = IDI_PROTOCOL;
|
|
nDialogTitle = IDS_SELECT_PROTOCOL;
|
|
nString = IDS_SELECT_OPTION_PROTOCOL;
|
|
}
|
|
|
|
// Set Icon
|
|
HICON hIcon = LoadIcon(g_hinst, MAKEINTRESOURCE(nIcon));
|
|
ASSERT(hIcon);
|
|
|
|
if (hIcon)
|
|
SendDlgItemMessage(hDlg, IDC_SELECT_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
|
|
|
|
// Build display strings
|
|
String fmt;
|
|
String type, data;
|
|
String text, text2;
|
|
|
|
// Dialog Title
|
|
fmt.LoadString(g_hinst, IDS_SELECT_TITLE);
|
|
type.LoadString(g_hinst, nDialogTitle);
|
|
text.Format(fmt, (LPCTSTR)type);
|
|
SetWindowText(hDlg, (LPCTSTR)text);
|
|
|
|
|
|
// Set static text to the correct context
|
|
fmt.LoadString(g_hinst, nString);
|
|
data.LoadString(g_hinst, nDialogTitle); // used later, don't modify
|
|
text.Format(fmt, (LPCTSTR)data);
|
|
fmt.LoadString(g_hinst, IDS_SELECT_OPTION_FMT);
|
|
text2.Format(fmt, (LPCTSTR)text);
|
|
SetDlgItemText(hDlg, IDC_DESCRIPTION, text2);
|
|
|
|
// Listview title
|
|
fmt.LoadString(g_hinst, IDS_SELECT_LV_TITLE);
|
|
text.Format(fmt, (LPCTSTR)data);
|
|
SetDlgItemText(hDlg, IDC_DESCRIPTIONSTATIC, text);
|
|
|
|
// Prepare Listview
|
|
m_list.InsertColumn(0, _T(" "));
|
|
GetClientRect(m_list, &rect);
|
|
rect.right -= GetSystemMetrics(SM_CXVSCROLL);
|
|
m_list.SetColumnWidth(0, rect.right);
|
|
|
|
m_list.DeleteAllItems();
|
|
fmt.LoadString(g_hinst, IDS_SELECT_LV_MESSAGE);
|
|
text.Format(fmt, (LPCTSTR)data);
|
|
|
|
// Building ... wait message
|
|
m_list.InsertItem(0, (LPCTSTR)text, m_nImage, (void*)-1);
|
|
|
|
// turn off ok button
|
|
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
|
|
|
|
// Sync the message queue creation and creat the worker thread
|
|
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
m_mainThread = GetCurrentThreadId();
|
|
|
|
|
|
// Disable HaveDisk button until the list is populated and reenable it in
|
|
// OnPrivateMessage
|
|
EnableWindow(GetDlgItem(hDlg, IDC_HAVEDISK), FALSE);
|
|
|
|
// If I create the list, start the thread
|
|
if (m_bDeleteList == TRUE)
|
|
{
|
|
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)BuildList, this, 0, &m_tid);
|
|
|
|
WaitForSingleObject(m_hEvent, INFINITE);
|
|
ResetEvent(m_hEvent); // reset event object to a known state
|
|
m_bWaitCursor = TRUE; // start wait cursor
|
|
}
|
|
else
|
|
OnPrivateMessage(); // list was provided, populate the listview
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CAddOptionDialog::SetSelectedItem(int nListItem)
|
|
{
|
|
int nCount = m_list.GetItemCount();
|
|
|
|
if (nCount == 0)
|
|
return FALSE;
|
|
|
|
delete m_pInfProduct;
|
|
m_pInfProduct = NULL;
|
|
|
|
if (nListItem < 0 || nListItem >= nCount)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
POSITION pos = m_optionList->GetHeadPosition();
|
|
InfProduct* pItem = NULL;
|
|
|
|
if (pos == NULL)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
// get the selected text from the list view and find it in the internal list
|
|
// Note: the items in the listview are sorted compared to the internal list
|
|
|
|
TCHAR buf[256]={0};
|
|
BOOL bMatch = FALSE;
|
|
|
|
m_list.GetItem(nListItem, 0, buf, _countof(buf)-1);
|
|
|
|
while(pos)
|
|
{
|
|
pItem = (InfProduct*)m_optionList->GetNext(pos);
|
|
ASSERT(pItem != NULL);
|
|
|
|
if(_tcscmp(buf, pItem->QueryDescription()) == 0)
|
|
{
|
|
bMatch = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
ASSERT(bMatch == TRUE);
|
|
m_pInfProduct = new InfProduct(*pItem);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CAddOptionDialog::GetSelectedItem(InfProduct* pItem)
|
|
{
|
|
ASSERT(pItem != NULL);
|
|
|
|
if (m_pInfProduct == NULL)
|
|
return FALSE;
|
|
|
|
*pItem = *m_pInfProduct;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CAddOptionDialog::OnCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (wParam == IDC_HAVEDISK)
|
|
{
|
|
OnHaveDisk();
|
|
return TRUE;
|
|
}
|
|
|
|
return CDialog::OnCommand(wParam, lParam);
|
|
}
|
|
|
|
BOOL CAddOptionDialog::OnNotify(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return m_list.OnNotify(wParam, lParam);
|
|
}
|
|
|
|
DWORD HaveDisk(LPDWORD lpdwParam)
|
|
{
|
|
CAddOptionDialog* dlg = (CAddOptionDialog*)lpdwParam;
|
|
HWND hDlg = *dlg;
|
|
|
|
ASSERT(dlg);
|
|
|
|
DWORD dwType = QIFT_SERVICES;
|
|
|
|
if (dlg->m_eType == ADAPTER)
|
|
{
|
|
dwType = QIFT_ADAPTERS;
|
|
}
|
|
else if(dlg->m_eType == PROTOCOL)
|
|
{
|
|
dwType = QIFT_PROTOCOLS;
|
|
}
|
|
|
|
SetEvent(dlg->m_hEvent);
|
|
|
|
ASSERT(dlg->m_pNcp != NULL);
|
|
dlg->m_pNcp->HaveDisk(hDlg, dwType);
|
|
|
|
PostMessage(*dlg, CDialog::PRIVATE_MSG, 0,0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CAddOptionDialog::OnHaveDisk()
|
|
{
|
|
UINT tid;
|
|
m_hHaveDiskThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HaveDisk, this, 0, &m_tid);
|
|
|
|
if (m_hHaveDiskThread)
|
|
{
|
|
m_bHaveDisk = TRUE;
|
|
ASSERT(m_hEvent);
|
|
WaitForSingleObject(m_hEvent, INFINITE);
|
|
ResetEvent(m_hEvent);
|
|
}
|
|
|
|
|
|
// REVIEW Disable Parent
|
|
EnableWindow(*this, FALSE);
|
|
}
|
|
|
|
BOOL CAddOptionDialog::OnSetCursor(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (HTCLIENT == LOWORD(lParam))
|
|
SetWaitCursor(m_bWaitCursor, IDC_APPSTARTING);
|
|
|
|
return m_bWaitCursor;
|
|
}
|
|
|
|
static const DWORD BUF_LEN= 512;
|
|
|
|
void CAddOptionDialog::OnPrivateMessage()
|
|
{
|
|
EnableWindow(GetDlgItem(*this, IDC_HAVEDISK), TRUE);
|
|
|
|
if (m_bHaveDisk == FALSE)
|
|
{
|
|
TRACE(_T("BuildList is done\n"));
|
|
|
|
m_list.DeleteAllItems(); // remove message from the list
|
|
POSITION pos;
|
|
|
|
m_bWaitCursor = FALSE;
|
|
pos = m_optionList->GetHeadPosition();
|
|
InfProduct* option;
|
|
|
|
EnableWindow(GetDlgItem(*this, IDOK), pos != NULL);
|
|
while(pos)
|
|
{
|
|
option = (InfProduct*)m_optionList->GetNext(pos);
|
|
m_list.InsertItem(m_list.GetItemCount(), option->QueryDescription(), m_nImage, 0);
|
|
}
|
|
|
|
// force 1 item to be selected
|
|
if(m_list.GetItemCount())
|
|
{
|
|
m_list.SetItemState(0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE(_T("Have Disk is done\n"));
|
|
m_bHaveDisk = FALSE; // have disk operation is done
|
|
EnableWindow(*this, TRUE);
|
|
|
|
// parse data from registry, fill in InfProduct item
|
|
TCHAR* buf = new TCHAR[BUF_LEN];
|
|
|
|
if (ReadSetupNetErrorKey(buf, BUF_LEN))
|
|
{
|
|
// if the key has the value STATUS_???????, the copied was canceled or failed
|
|
if (_tcsncmp(buf, _T("STATUS_"), 7) != 0)
|
|
{
|
|
// create a new InfProduct and populate it
|
|
InfProduct* inf = new InfProduct;
|
|
int nLen = 0;
|
|
LPTSTR ptr[4] = {NULL, NULL, NULL, NULL};
|
|
TCHAR tmp[BUF_LEN] = {NULL};
|
|
LPTSTR pTmp = tmp;
|
|
|
|
// get tokens and match order needed for InitFromBuffer
|
|
ptr[2] = _tcstok(buf , _T(",")); // filename
|
|
ASSERT(ptr[2] != NULL);
|
|
ptr[3] = _tcstok(NULL , _T(",")); // path
|
|
ptr[0] = _tcstok(NULL , _T(",")); // option
|
|
ptr[1] = _tcstok(NULL , _T(",")); // description
|
|
|
|
for (int i=0; i < 4; i++)
|
|
{
|
|
if (ptr[i] == NULL)
|
|
continue;
|
|
|
|
nLen = _tcslen(ptr[i]);
|
|
_tcsncpy(pTmp, ptr[i], nLen);
|
|
pTmp[nLen] = NULL;
|
|
|
|
pTmp += (nLen + 1);
|
|
}
|
|
|
|
inf->InitFromBuffer(tmp);
|
|
if (ptr[3] )
|
|
{
|
|
inf->AddOEMPath(ptr[3]);
|
|
|
|
}
|
|
TRACE(_T("FileName:%s Option:%s Description:%s Path: %s\n"), inf->QueryFileName(), inf->QueryOption(),
|
|
inf->QueryDescription(), inf->QueryPathInfo());
|
|
|
|
m_pInfProduct = inf;
|
|
CDialog::OnOk(); // we're done
|
|
}
|
|
else
|
|
{
|
|
SetActiveWindow(*this);
|
|
}
|
|
}
|
|
|
|
delete [] buf;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void CAddOptionDialog::OnOk()
|
|
{
|
|
// see if there is an item selected
|
|
int nItem = m_list.GetCurrentSelection();
|
|
|
|
VERIFY(SetSelectedItem(nItem));
|
|
|
|
CDialog::OnOk();
|
|
}
|
|
|
|
void CAddOptionDialog::OnCancel()
|
|
{
|
|
CDialog::OnCancel();
|
|
}
|
|
|
|
void CAddOptionDialog::TerminateThread()
|
|
{
|
|
if (m_tid)
|
|
{
|
|
PostThreadMessage(m_tid, TERMINATE_THREAD, 0, 0);
|
|
WaitForSingleObject(m_hThread, INFINITE);
|
|
}
|
|
}
|
|
|
|
void CAddOptionDialog::OnDestroy()
|
|
{
|
|
TerminateThread();
|
|
|
|
if (m_hThread)
|
|
{
|
|
CloseHandle(m_hThread);
|
|
m_hThread = 0;
|
|
}
|
|
|
|
if (m_hEvent)
|
|
{
|
|
CloseHandle(m_hEvent);
|
|
m_hEvent = 0;
|
|
}
|
|
|
|
if (m_hHaveDiskThread)
|
|
{
|
|
CloseHandle(m_hHaveDiskThread);
|
|
m_hHaveDiskThread = 0;
|
|
}
|
|
|
|
if (m_bDeleteList == TRUE)
|
|
{
|
|
POSITION pos = m_optionList->GetHeadPosition();
|
|
InfProduct* pItem;
|
|
|
|
while(pos)
|
|
{
|
|
pItem = (InfProduct*)m_optionList->GetNext(pos);
|
|
delete pItem;
|
|
}
|
|
|
|
if (m_optionList->GetCount())
|
|
m_optionList->RemoveAll();
|
|
}
|
|
|
|
if (m_hImage)
|
|
ImageList_Destroy(m_hImage);
|
|
}
|
|
|
|
DWORD BuildList(LPDWORD lpdwParam)
|
|
{
|
|
BOOL bListDone = FALSE;
|
|
CAddOptionDialog* dlg = (CAddOptionDialog*)lpdwParam;
|
|
|
|
ASSERT(dlg != NULL);
|
|
ASSERT(dlg->m_mainThread);
|
|
ASSERT(dlg->m_hEvent);
|
|
|
|
MSG msg;
|
|
TRACE(_T("BuildList thread Started\n"));
|
|
|
|
// Create the queue and signal the main thread
|
|
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
|
SetEvent(dlg->m_hEvent);
|
|
|
|
// Determine which options are needed
|
|
DWORD dwType = QIFT_SERVICES;
|
|
|
|
if (dlg->m_eType == ADAPTER)
|
|
{
|
|
dwType = QIFT_ADAPTERS;
|
|
}
|
|
else if(dlg->m_eType == PROTOCOL)
|
|
{
|
|
dwType = QIFT_PROTOCOLS;
|
|
}
|
|
|
|
// Launch setup and read options
|
|
LPTSTR pszBuff;
|
|
LPTSTR pchBuff;
|
|
InfProduct* pinfp;
|
|
InfProduct* pinfpPrev;
|
|
|
|
|
|
// Are we told to terminate
|
|
if (PeekMessage(&msg, NULL, TERMINATE_THREAD, TERMINATE_THREAD, PM_REMOVE))
|
|
return 0;
|
|
|
|
ASSERT(dlg->m_pNcp != NULL);
|
|
|
|
dlg->m_pNcp->RunUpdateRegOemInfs(NULL, dwType);
|
|
|
|
// retrieve buffer of services
|
|
pszBuff = dlg->m_pNcp->GetAllOptionsText(dwType);
|
|
pchBuff = pszBuff;
|
|
POSITION poslist;
|
|
POSITION posCurrent;
|
|
|
|
if (NULL != pszBuff)
|
|
{
|
|
// append buffer items onto our list
|
|
do
|
|
{
|
|
pinfp = new InfProduct;
|
|
pchBuff += pinfp->InitFromBuffer(pchBuff);
|
|
|
|
// check if option/filename matches a previous entry,
|
|
// if so, remove the previous entry before append to list
|
|
// NOTE: Only one previous entry could be present, so break
|
|
// out when one is found and removed.
|
|
//
|
|
poslist = dlg->m_optionList->GetTailPosition();
|
|
while (NULL != poslist)
|
|
{
|
|
posCurrent = poslist;
|
|
|
|
pinfpPrev = (InfProduct*)dlg->m_optionList->GetPrev( poslist );
|
|
|
|
if (0 == lstrcmp(pinfpPrev->QueryOption(), pinfp->QueryOption() ) )
|
|
{
|
|
// remove the dup
|
|
dlg->m_optionList->RemoveAt( posCurrent );
|
|
break;
|
|
}
|
|
}
|
|
dlg->m_optionList->AddTail(pinfp);
|
|
|
|
} while (*pchBuff!= NULL);
|
|
|
|
delete [] pszBuff;
|
|
}
|
|
|
|
// tell the main thread that the list is complete
|
|
PostMessage(*dlg, CDialog::PRIVATE_MSG, 0,0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL SelectComponent(HWND hParent,
|
|
OptionTypes eType,
|
|
DLIST_OF_InfProduct* pdlinfProduct,
|
|
InfProduct& infpSelected,
|
|
NCP* pncp,
|
|
DLIST_OF_InfProduct* pdlinfUIProduct )
|
|
{
|
|
BOOL frt = FALSE;
|
|
ASSERT(IsWindow(hParent));
|
|
CPtrList* pcplList = NULL;
|
|
CPtrList cplList;
|
|
|
|
// did they supply a list to use
|
|
//
|
|
if (pdlinfProduct != NULL)
|
|
{
|
|
InfProduct* pinf;
|
|
|
|
//
|
|
// BUGBUG: We are converting lists here, we should use one list
|
|
// class
|
|
//
|
|
ITER_DL_OF(InfProduct) iterInf( * pdlinfProduct );
|
|
|
|
for ( ; pinf = iterInf.Next() ; )
|
|
{
|
|
BOOL fAppend = TRUE;
|
|
|
|
if (NULL != pdlinfUIProduct)
|
|
{
|
|
InfProduct* pinfUI;
|
|
ITER_DL_OF(InfProduct) iterUIInf( * pdlinfUIProduct );
|
|
// don't add it if it is present in the UI already
|
|
//
|
|
while ( pinfUI = iterUIInf.Next() )
|
|
{
|
|
if (0 == lstrcmpi( pinf->QueryOption(), pinfUI->QueryOption() ))
|
|
{
|
|
fAppend = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (fAppend)
|
|
{
|
|
cplList.AddTail(pinf);
|
|
}
|
|
}
|
|
|
|
pcplList = &cplList;
|
|
}
|
|
|
|
CAddOptionDialog dlg(eType, pncp, pcplList);
|
|
|
|
dlg.Create(hParent, g_hinst, IDD_SELECTNEW, PSZ_NETWORKHELP, (PDWORD)amhidsSelection);
|
|
if (dlg.DoModal() == IDOK)
|
|
{
|
|
|
|
if (dlg.GetSelectedItem(&infpSelected) == TRUE)
|
|
{
|
|
frt = TRUE;
|
|
TRACE(_T("Component Selected %s\n"), (LPCTSTR)infpSelected.QueryDescription());
|
|
}
|
|
}
|
|
|
|
if (cplList.GetCount())
|
|
cplList.RemoveAll();
|
|
|
|
return( frt );
|
|
}
|
|
|
|
BOOL CreateWSTR(LPWSTR* ppszWStr, LPWSTR pszStr)
|
|
{
|
|
int cchConv;
|
|
LPWSTR pszConv;
|
|
BOOL frt = FALSE;
|
|
|
|
if (NULL == pszStr)
|
|
{
|
|
*ppszWStr = NULL;
|
|
frt = TRUE;
|
|
}
|
|
else
|
|
{
|
|
cchConv = lstrlen( pszStr ) + 1;
|
|
|
|
pszConv = new WCHAR[cchConv];
|
|
if (NULL != pszConv)
|
|
{
|
|
lstrcpy( pszConv, pszStr );
|
|
*ppszWStr = pszConv;
|
|
frt = TRUE;
|
|
}
|
|
}
|
|
return( frt );
|
|
}
|
|
|
|
InfProduct::InfProduct()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
InfProduct::InfProduct(const InfProduct& inf)
|
|
{
|
|
Initialize();
|
|
CopyItem(inf);
|
|
}
|
|
|
|
InfProduct::InfProduct(LPTSTR szInfName,
|
|
LPTSTR szInfOption,
|
|
LPTSTR szTitle,
|
|
LPTSTR szDetectInfo,
|
|
LPTSTR szPath,
|
|
LPTSTR szRegBase,
|
|
LPTSTR szSection)
|
|
{
|
|
Initialize();
|
|
if (szInfOption)
|
|
{
|
|
_pszOption = new TCHAR[_tcslen(szInfOption) + 1];
|
|
_tcscpy(_pszOption, szInfOption);
|
|
}
|
|
if (szTitle)
|
|
{
|
|
_pszDescription = new TCHAR[_tcslen(szTitle) + 1];
|
|
_tcscpy(_pszDescription, szTitle);
|
|
}
|
|
|
|
if (szPath)
|
|
{
|
|
_pszPath = new TCHAR[_tcslen(szPath) + 1];
|
|
_tcscpy(_pszPath, szPath);
|
|
}
|
|
|
|
if (szInfName)
|
|
{
|
|
_pszFileName = new TCHAR[_tcslen(szInfName) + 1];
|
|
_tcscpy(_pszFileName, szInfName);
|
|
}
|
|
|
|
if (szDetectInfo)
|
|
{
|
|
_pszDetectInfo = new TCHAR[_tcslen(szDetectInfo) + 1];
|
|
_tcscpy(_pszDetectInfo, szDetectInfo);
|
|
}
|
|
if (szRegBase)
|
|
{
|
|
_pszRegBase = new TCHAR[_tcslen(szRegBase) + 1];
|
|
_tcscpy(_pszRegBase, szRegBase);
|
|
}
|
|
if (szSection)
|
|
{
|
|
_pszSection = new TCHAR[_tcslen(szSection) + 1];
|
|
_tcscpy(_pszSection, szSection);
|
|
}
|
|
|
|
}
|
|
|
|
InfProduct& InfProduct::operator = (const InfProduct& inf)
|
|
{
|
|
if (this == &inf)
|
|
return *this;
|
|
|
|
this->~InfProduct();
|
|
|
|
CopyItem(inf);
|
|
return *this;
|
|
}
|
|
|
|
void InfProduct::CopyItem(const InfProduct& inf)
|
|
{
|
|
ASSERT(inf._pszOption != NULL);
|
|
ASSERT(inf._pszDescription != NULL);
|
|
ASSERT(inf._pszFileName != NULL);
|
|
|
|
_fState = inf._fState;
|
|
|
|
if (inf._pszOption)
|
|
{
|
|
_pszOption = new TCHAR[_tcslen(inf._pszOption) + 1];
|
|
_tcscpy(_pszOption, inf._pszOption);
|
|
}
|
|
|
|
if (inf._pszDescription)
|
|
{
|
|
_pszDescription = new TCHAR[_tcslen(inf._pszDescription) + 1];
|
|
_tcscpy(_pszDescription, inf._pszDescription);
|
|
}
|
|
|
|
if (inf._pszPath)
|
|
{
|
|
_pszPath = new TCHAR[_tcslen(inf._pszPath) + 1];
|
|
_tcscpy(_pszPath, inf._pszPath);
|
|
}
|
|
|
|
if (inf._pszFileName)
|
|
{
|
|
_pszFileName = new TCHAR[_tcslen(inf._pszFileName) + 1];
|
|
_tcscpy(_pszFileName, inf._pszFileName);
|
|
}
|
|
|
|
if (inf._pszDetectInfo)
|
|
{
|
|
_pszDetectInfo = new TCHAR[_tcslen(inf._pszDetectInfo) + 1];
|
|
_tcscpy(_pszDetectInfo, inf._pszDetectInfo);
|
|
}
|
|
if (inf._pszRegBase)
|
|
{
|
|
_pszRegBase = new TCHAR[_tcslen(inf._pszRegBase) + 1];
|
|
_tcscpy(_pszRegBase, inf._pszRegBase);
|
|
}
|
|
if (inf._pszSection)
|
|
{
|
|
_pszSection = new TCHAR[_tcslen(inf._pszSection) + 1];
|
|
_tcscpy(_pszSection, inf._pszSection);
|
|
}
|
|
}
|
|
|
|
InfProduct::~InfProduct()
|
|
{
|
|
delete [] _pszFileName;
|
|
delete [] _pszOption;
|
|
delete [] _pszDescription;
|
|
delete [] _pszPath;
|
|
delete [] _pszDetectInfo;
|
|
delete [] _pszRegBase;
|
|
delete [] _pszSection;
|
|
Initialize();
|
|
}
|
|
|
|
void InfProduct::Initialize()
|
|
{
|
|
_pszFileName = NULL;
|
|
_pszOption = NULL,
|
|
_pszDescription = NULL;
|
|
_pszPath = NULL;
|
|
_pszDetectInfo = NULL;
|
|
_pszRegBase = NULL;
|
|
_pszSection = NULL;
|
|
_fState = 0;
|
|
_crefForce = 0;
|
|
}
|
|
|
|
void InfProduct::ResetRegBase( LPCTSTR pszRegBase )
|
|
{
|
|
// note that it is valid to pass a null pszRegBase
|
|
delete [] _pszRegBase;
|
|
_pszRegBase = NULL;
|
|
|
|
if (pszRegBase)
|
|
{
|
|
_pszRegBase = new TCHAR[_tcslen(pszRegBase) + 1];
|
|
_tcscpy(_pszRegBase, pszRegBase);
|
|
}
|
|
}
|
|
|
|
void InfProduct::ResetUnattendSection( LPCTSTR lpszSection )
|
|
{
|
|
// note that it is valid to pass a null lpszSection
|
|
delete [] _pszSection;
|
|
_pszSection = NULL;
|
|
|
|
if (lpszSection)
|
|
{
|
|
_pszSection = new TCHAR[_tcslen(lpszSection) + 1];
|
|
_tcscpy(_pszSection, lpszSection);
|
|
}
|
|
}
|
|
|
|
void InfProduct::ResetFileName( LPCTSTR pszFileName )
|
|
{
|
|
ASSERT(_pszFileName != NULL);
|
|
|
|
delete [] _pszFileName;
|
|
_pszFileName = NULL;
|
|
|
|
if (pszFileName)
|
|
{
|
|
_pszFileName = new TCHAR[_tcslen(pszFileName) + 1];
|
|
_tcscpy(_pszFileName, pszFileName);
|
|
}
|
|
}
|
|
|
|
/* BUGBUG: Because InitFromBuffer() does not know how to deal with the oem path
|
|
* a separate, this member is needed. The way the list of infproducts is built
|
|
* has to be revamped
|
|
*/
|
|
|
|
void InfProduct::AddOEMPath(TCHAR* lpszPath)
|
|
{
|
|
ASSERT(lpszPath != NULL);
|
|
int cchSize = _tcslen(lpszPath);
|
|
delete [] _pszPath;
|
|
|
|
|
|
// add trailing \ if not present
|
|
if (lpszPath[cchSize-1] != _T('\\'))
|
|
{
|
|
cchSize++;
|
|
}
|
|
|
|
_pszPath = new TCHAR[cchSize + 1];
|
|
_tcscpy(_pszPath, lpszPath);
|
|
|
|
_pszPath[cchSize-1] = _T('\\');
|
|
_pszPath[cchSize] = _T('\0');
|
|
|
|
}
|
|
|
|
int InfProduct::InitFromBuffer(LPTSTR pszBuff)
|
|
{
|
|
int cchSize;
|
|
int cchTotal = 0;
|
|
|
|
if (NULL != pszBuff)
|
|
{
|
|
// buffer points to option
|
|
cchSize = lstrlen( pszBuff ) + 1;
|
|
CreateWSTR(&_pszOption, pszBuff);
|
|
|
|
cchTotal += cchSize;
|
|
|
|
pszBuff += cchSize;
|
|
|
|
// buffer points to description
|
|
cchSize = lstrlen( pszBuff ) + 1;
|
|
CreateWSTR(&_pszDescription, pszBuff);
|
|
|
|
cchTotal += cchSize;
|
|
|
|
pszBuff += cchSize;
|
|
// buffer points to filename
|
|
cchSize = lstrlen( pszBuff ) + 1;
|
|
CreateWSTR( &_pszFileName, pszBuff );
|
|
|
|
cchTotal += cchSize;
|
|
}
|
|
return(cchTotal);
|
|
};
|
|
|
|
//-------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return;
|
|
//
|
|
// Notes: creates a INF list type { "", "", ... }
|
|
//
|
|
// History:
|
|
// Sept 21, 1995 MikeMi - Created
|
|
//
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
static const INT MAX_INFO = 1024;
|
|
|
|
static void appendstring( PWSTR pszBuff, PCWSTR pszStr )
|
|
{
|
|
|
|
// because this item is in a list that will be included in anther list,
|
|
// all items must have extra quotes for each depth of containment into a list
|
|
//
|
|
lstrcat( pszBuff, PSZ_QUOTE );
|
|
lstrcat( pszBuff, PSZ_QUOTE );
|
|
lstrcat( pszBuff, pszStr );
|
|
lstrcat( pszBuff, PSZ_QUOTE );
|
|
lstrcat( pszBuff, PSZ_QUOTE );
|
|
|
|
}
|
|
|
|
static void appendnumber( PWSTR pszBuff, INT nValue )
|
|
{
|
|
WCHAR pszTemp[32];
|
|
|
|
wsprintf( pszTemp, L"%i", nValue );
|
|
appendstring( pszBuff, pszTemp );
|
|
}
|
|
|
|
INT InfProduct::SetDetectInfo( CARD_REFERENCE* pCardRef, INT iCard )
|
|
{
|
|
WCHAR pszInfo[MAX_INFO];
|
|
|
|
lstrcpy( pszInfo, PSZ_BEGINBRACE );
|
|
appendstring( pszInfo, pCardRef->QueryCardType()->QueryOptionName() );
|
|
lstrcat( pszInfo, PSZ_COMMA );
|
|
|
|
appendnumber( pszInfo, iCard );
|
|
lstrcat( pszInfo, PSZ_COMMA );
|
|
|
|
appendnumber( pszInfo, pCardRef->QueryCardType()->QueryType() );
|
|
lstrcat( pszInfo, PSZ_COMMA );
|
|
|
|
appendnumber( pszInfo, pCardRef->QueryConfidence() );
|
|
lstrcat( pszInfo, PSZ_COMMA );
|
|
|
|
appendnumber( pszInfo, (INT) pCardRef->QueryIfType() );
|
|
lstrcat( pszInfo, PSZ_COMMA );
|
|
|
|
appendnumber( pszInfo, pCardRef->QueryBus() );
|
|
|
|
lstrcat( pszInfo, PSZ_ENDBRACE );
|
|
|
|
int cch = lstrlen( pszInfo );
|
|
_pszDetectInfo = new WCHAR[cch+1];
|
|
lstrcpy( _pszDetectInfo, pszInfo );
|
|
|
|
return( cch );
|
|
}
|
|
|
|
const WCHAR PSZ_SETUPKEYNAME[] = L"SOFTWARE\\Microsoft\\Ncpa";
|
|
const WCHAR PSZ_NETERRORNAME[] = L"InfReturn";
|
|
|
|
BOOL ReadSetupNetErrorKey(PWSTR pszBuf, DWORD cchLen)
|
|
{
|
|
ASSERT(pszBuf != NULL);
|
|
ASSERT(cchLen);
|
|
|
|
HKEY hkeySetup;
|
|
DWORD cbSize;
|
|
DWORD dwType;
|
|
|
|
LONG lrt;
|
|
|
|
// open the keys we need
|
|
lrt = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
PSZ_SETUPKEYNAME,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hkeySetup );
|
|
if (ERROR_SUCCESS == lrt)
|
|
{
|
|
cbSize = sizeof( WCHAR ) * cchLen;
|
|
lrt = RegQueryValueEx( hkeySetup,
|
|
PSZ_NETERRORNAME,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)pszBuf,
|
|
&cbSize );
|
|
RegCloseKey( hkeySetup );
|
|
}
|
|
return (ERROR_SUCCESS == lrt);
|
|
}
|
|
|