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.
1103 lines
23 KiB
1103 lines
23 KiB
//
|
|
// Copyright (c) 1996 Microsoft Corporation
|
|
//
|
|
//
|
|
// DEV.C -- Implementation for Classes:
|
|
// CInfDevice
|
|
//
|
|
//
|
|
// History:
|
|
// 05/22/96 JosephJ Created
|
|
//
|
|
//
|
|
#include "common.h"
|
|
#include "ini.h"
|
|
#include "inf.h"
|
|
#include "dev.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// CLASS CInfDevice
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//-------------- Dump ------------------
|
|
// Dump state
|
|
void CInfDevice::Dump(void) const
|
|
{
|
|
// Dump Version
|
|
m_pVersion->Dump();
|
|
|
|
// Dump manufacturer name
|
|
m_pSymManufacturerName->Dump();
|
|
|
|
// Dump model name
|
|
m_pSymDeviceName->Dump();
|
|
|
|
// Dump AddRegList
|
|
{
|
|
const CInfList *pList = m_pAddRegList;
|
|
|
|
for (;pList; pList=pList->Next())
|
|
{
|
|
const CInfAddRegEntry * pAddRegEntry =
|
|
(const CInfAddRegEntry *) pList->GetData();
|
|
pAddRegEntry->Dump();
|
|
}
|
|
|
|
}
|
|
|
|
// Dump CopyFilesList
|
|
{
|
|
const CInfList *pList = m_pCopyFilesList;
|
|
|
|
for (;pList; pList=pList->Next())
|
|
{
|
|
const CInfCopyFilesEntry * pCopyFilesEntry =
|
|
(const CInfCopyFilesEntry *) pList->GetData();
|
|
pCopyFilesEntry->Dump();
|
|
}
|
|
|
|
}
|
|
|
|
// NoResDup section
|
|
{
|
|
// [Modem6.NoResDup]
|
|
// UNIMODEMCC646872,UNIMODEMA4970248,UNIMODEMB6071C15
|
|
|
|
// TODO: unimplemented
|
|
|
|
}
|
|
|
|
// PosDup section
|
|
{
|
|
// [Modem12.PosDup]
|
|
// *PNP0500
|
|
|
|
// TODO: unimplemented
|
|
}
|
|
// TODO: UpdateInis, Uninstall, NoResDup, PosDup
|
|
|
|
}
|
|
|
|
|
|
//-------------- Load ------------------
|
|
// Load (init), using information from the specified inf file and model entry.
|
|
BOOL CInfDevice::Load
|
|
(
|
|
const CInfFile *pInf,
|
|
const CInfManufacturerEntry *pManuE,
|
|
const CInfModelEntry *pModelE
|
|
)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
mfn_EnterCrit();
|
|
|
|
// TODO: call m_sync.BeginLoad
|
|
|
|
ASSERT
|
|
(
|
|
!m_pvInfSession
|
|
&& !m_pInfFile
|
|
&& !m_pManufacturerEntry
|
|
&& !m_pModelEntry
|
|
&& !m_pVersion
|
|
&& !m_pSymManufacturerName
|
|
&& !m_pSymDeviceName
|
|
&& !m_pCopyFilesList
|
|
&& !m_pAddRegList
|
|
);
|
|
|
|
if (!pInf || !pManuE || !pModelE) goto end;
|
|
|
|
// Keep a reference to the Inf file and manufacturer and model entry
|
|
m_pInfFile = pInf;
|
|
m_pModelEntry = pModelE;
|
|
m_pManufacturerEntry = pManuE;
|
|
|
|
// Open a session with the inf file.
|
|
m_pvInfSession = pInf->OpenSession ();
|
|
|
|
if (!m_pvInfSession)
|
|
{
|
|
printf("Error calling pInf->OpenSession()\n");
|
|
goto end;
|
|
}
|
|
|
|
// version
|
|
m_pVersion = pInf->GetVersion();
|
|
|
|
// manufacturer name
|
|
m_pSymManufacturerName = pManuE->GetName();
|
|
|
|
// model name
|
|
m_pSymDeviceName = pModelE->GetName();
|
|
|
|
// TODO: UpdateInis, Uninstall
|
|
|
|
if (
|
|
m_pvInfSession
|
|
&& m_pInfFile
|
|
&& m_pModelEntry
|
|
&& m_pManufacturerEntry
|
|
&& m_pVersion
|
|
&& m_pSymManufacturerName
|
|
&& m_pSymDeviceName
|
|
)
|
|
{
|
|
fRet = mfn_CreateAddRegList(pModelE);
|
|
fRet = fRet && mfn_CreateCopyFilesList(pModelE);
|
|
}
|
|
|
|
// Create signatures
|
|
|
|
// Version
|
|
m_dwSigVersion = m_pVersion->Checksum();
|
|
|
|
// Make and Model
|
|
m_dwSigManuAndModel = m_pSymManufacturerName->Checksum();
|
|
AddToChecksumDW(&m_dwSigManuAndModel, m_pSymDeviceName->Checksum());
|
|
|
|
// Control Flags
|
|
m_dwSigFlags = m_pModelEntry->GetControlFlags(ePLAT_ALL);
|
|
AddToChecksumDW(&m_dwSigFlags,m_pModelEntry->GetControlFlags(ePLAT_NT_ALL));
|
|
AddToChecksumDW(&m_dwSigFlags,m_pModelEntry->GetControlFlags(ePLAT_NT_ALPHA));
|
|
AddToChecksumDW(&m_dwSigFlags,m_pModelEntry->GetControlFlags(ePLAT_NT_PPC));
|
|
AddToChecksumDW(&m_dwSigFlags,m_pModelEntry->GetControlFlags(ePLAT_NT_MIPS));
|
|
|
|
// AddReg -- got created by mfn_CreateAddRegList
|
|
|
|
// Copy files -- got created by mfn_CreateCopyFilesList
|
|
|
|
// NoResDup and PosDup
|
|
{
|
|
const CInfInstallSection *pInstall = m_pModelEntry->GetInstallSection();
|
|
DWORD dwSigNoResDup=0;
|
|
DWORD dwSigPosDup=0;
|
|
const CInfList *pSymList = pInstall->GetNoResDupIDList();
|
|
while(pSymList)
|
|
{
|
|
const CInfSymbol *pSym = (const CInfSymbol *) pSymList->GetData();
|
|
// We use XOR to combine the checksum, because we don't care about
|
|
// order.
|
|
dwSigNoResDup ^= pSym->Checksum();
|
|
pSymList = pSymList->Next();
|
|
}
|
|
|
|
pSymList = pInstall->GetPosDupIDList();
|
|
while(pSymList)
|
|
{
|
|
const CInfSymbol *pSym = (const CInfSymbol *) pSymList->GetData();
|
|
// We use XOR to combine the checksum, because we don't care about
|
|
// order.
|
|
dwSigPosDup ^= pSym->Checksum();
|
|
pSymList = pSymList->Next();
|
|
}
|
|
|
|
// Combine, and this time we *are* sensitive to the order.
|
|
m_dwSigDup = dwSigNoResDup;
|
|
AddToChecksumDW(&m_dwSigDup, dwSigPosDup);
|
|
}
|
|
|
|
// Rank0
|
|
m_dwSigRank0 = (m_pModelEntry->GetRank0ID())->Checksum();
|
|
|
|
// All ranks
|
|
m_dwSigRanks = m_dwSigRank0;
|
|
AddToChecksumDW(&m_dwSigRanks, (m_pModelEntry->GetRank1ID())->Checksum());
|
|
AddToChecksumDW(&m_dwSigRanks, (m_pModelEntry->GetRank2ID())->Checksum());
|
|
|
|
// Signature of everything.
|
|
m_dwSigAll = m_dwSigVersion;
|
|
AddToChecksumDW(&m_dwSigAll, m_dwSigManuAndModel);
|
|
AddToChecksumDW(&m_dwSigAll, m_dwSigFlags);
|
|
AddToChecksumDW(&m_dwSigAll, m_dwSigAddReg);
|
|
AddToChecksumDW(&m_dwSigAll, m_dwSigCopyFiles);
|
|
AddToChecksumDW(&m_dwSigAll, m_dwSigDup);
|
|
AddToChecksumDW(&m_dwSigAll, m_dwSigRanks);
|
|
|
|
end:
|
|
if (!fRet)
|
|
{
|
|
mfn_Cleanup();
|
|
}
|
|
|
|
mfn_LeaveCrit();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
//-------------- Unload ------------------
|
|
// Unloads a previously loaded file.
|
|
HANDLE CInfDevice::Unload (void)
|
|
{
|
|
HANDLE hUnload = NULL;
|
|
|
|
mfn_EnterCrit();
|
|
|
|
// TODO: call m_sync.BeginUnload to try to put us in unloadable state.
|
|
|
|
mfn_Cleanup();
|
|
|
|
mfn_LeaveCrit();
|
|
|
|
return hUnload;
|
|
}
|
|
|
|
//-------------- WriteInf ------------------
|
|
// Creates an inf file with all the information of this device.
|
|
BOOL CInfDevice::WriteInf(LPCTSTR lpctszIniFile) const
|
|
{
|
|
// String-related constants
|
|
LPCTSTR lpctszStrings = TEXT("Strings");
|
|
|
|
BOOL fRet = FALSE;
|
|
const CInfSymbol * pSym=NULL;
|
|
|
|
printf(TEXT("Writing inf [%s]\n"), lpctszIniFile);
|
|
|
|
// Create/truncate file, and write header comment
|
|
if (!mfn_write_header(lpctszIniFile)) goto end;
|
|
|
|
end:
|
|
return fRet;
|
|
}
|
|
|
|
|
|
// Cleanup by freeing any allocated resources.
|
|
void CInfDevice::mfn_Cleanup (void)
|
|
{
|
|
mfn_EnterCrit();
|
|
|
|
// TODO: ASSERT(state == loading or state == unloading)
|
|
|
|
if (m_pAddRegList)
|
|
{
|
|
// Explicitly cast to non-const because we're deleting it.
|
|
CInfList::FreeList((CInfList *) m_pAddRegList);
|
|
}
|
|
|
|
if (m_pCopyFilesList)
|
|
{
|
|
// Explicitly cast to non-const because we're deleting it.
|
|
CInfList::FreeList((CInfList *) m_pCopyFilesList);
|
|
}
|
|
|
|
if (m_pvInfSession)
|
|
{
|
|
ASSERT(m_pInfFile);
|
|
m_pInfFile->CloseSession(m_pvInfSession);
|
|
}
|
|
|
|
m_pAddRegList = NULL;
|
|
m_pCopyFilesList = NULL;
|
|
m_pvInfSession = NULL;
|
|
m_pInfFile = NULL;
|
|
m_pModelEntry = NULL;
|
|
m_pManufacturerEntry = NULL;
|
|
m_pVersion = NULL;
|
|
m_pSymManufacturerName = NULL;
|
|
m_pSymDeviceName = NULL;
|
|
|
|
m_dwSigVersion = 0;
|
|
m_dwSigManuAndModel = 0;
|
|
m_dwSigFlags = 0;
|
|
m_dwSigAddReg = 0;
|
|
m_dwSigCopyFiles = 0;
|
|
m_dwSigRank0 = 0;
|
|
m_dwSigRanks = 0;
|
|
|
|
|
|
mfn_LeaveCrit();
|
|
}
|
|
|
|
|
|
// Initializes m_pAddRegList to list of addreg entries.
|
|
BOOL CInfDevice::mfn_CreateAddRegList(const CInfModelEntry *pModelE)
|
|
{
|
|
const CInfInstallSection * pInstall = pModelE->GetInstallSection();
|
|
const CInfList * pAddRegList = pInstall->GetAddRegSectionList();
|
|
|
|
ASSERT(!m_pAddRegList);
|
|
|
|
// Initialize this here -- it is modified by mfn_AddToAddRegList.
|
|
m_dwSigAddReg = 0;
|
|
|
|
// Walk AddReg list, adding each entry for each addreg section.
|
|
for (;pAddRegList; pAddRegList=pAddRegList->Next())
|
|
{
|
|
const CInfAddRegSection * pAddRegSection =
|
|
(const CInfAddRegSection *) pAddRegList->GetData();
|
|
|
|
ASSERT(pAddRegSection);
|
|
|
|
// Add all the entries in the section, overwriting previous entries
|
|
// with the same subkey/value-name.
|
|
const CInfAddRegEntry * pAddRegEntry =
|
|
pAddRegSection->GetFirstAddRegEntry ();
|
|
for(;pAddRegEntry; pAddRegEntry = pAddRegEntry->Next())
|
|
{
|
|
mfn_AddToAddRegList(pAddRegEntry);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CInfDevice::mfn_AddToAddRegList (const CInfAddRegEntry *pAddRegEntry)
|
|
{
|
|
// TODO: need to overwrite or not, depending on the addreg flags.
|
|
// for now, simply add to front of list.
|
|
m_pAddRegList = new CInfList ((void *) pAddRegEntry, m_pAddRegList);
|
|
AddToChecksumDW(&m_dwSigAddReg, pAddRegEntry->Checksum());
|
|
}
|
|
|
|
BOOL CInfDevice::mfn_CreateCopyFilesList(const CInfModelEntry *pModelE)
|
|
{
|
|
|
|
const CInfInstallSection * pInstall = pModelE->GetInstallSection();
|
|
const CInfList * pCopyFilesList = pInstall->GetCopyFilesSectionList();
|
|
|
|
ASSERT(!m_pCopyFilesList);
|
|
|
|
// Initialize this here -- it is modified by mfn_AddToCopyFilesList.
|
|
m_dwSigCopyFiles = 0;
|
|
|
|
// Walk CopyFiles list, adding each entry for each copyfile section.
|
|
for (;pCopyFilesList; pCopyFilesList=pCopyFilesList->Next())
|
|
{
|
|
const CInfCopyFilesSection * pCopyFilesSection =
|
|
(const CInfCopyFilesSection *) pCopyFilesList->GetData();
|
|
|
|
ASSERT(pCopyFilesSection);
|
|
|
|
// Add all the entries in the section, overwriting previous entries
|
|
// with the name and destination.
|
|
const CInfCopyFilesEntry * pCopyFilesEntry =
|
|
pCopyFilesSection->GetFirstCopyFilesEntry();
|
|
for(;pCopyFilesEntry; pCopyFilesEntry = pCopyFilesEntry->Next())
|
|
{
|
|
mfn_AddToCopyFilesList(pCopyFilesEntry);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CInfDevice::mfn_AddToCopyFilesList (
|
|
const CInfCopyFilesEntry *pCopyFilesEntry
|
|
)
|
|
{
|
|
// TODO: need to overwrite or not, depending on the addreg flags.
|
|
// for now, simply add to front of list.
|
|
m_pCopyFilesList = new CInfList (
|
|
(void *) pCopyFilesEntry,
|
|
m_pCopyFilesList
|
|
);
|
|
AddToChecksumDW(&m_dwSigCopyFiles, pCopyFilesEntry->Checksum());
|
|
}
|
|
|
|
|
|
|
|
// Create/Truncate inf file for just this device, and write header.
|
|
BOOL CInfDevice::mfn_write_header (
|
|
LPCTSTR lpctszIniFile
|
|
)
|
|
const
|
|
{
|
|
LPCTSTR lpctszOrigFile = TEXT("");
|
|
LPCTSTR lpctszManuS = TEXT("");
|
|
LPCTSTR lpctszManuName = TEXT("");
|
|
LPCTSTR lpctszModelLHS = TEXT("");
|
|
LPCTSTR lpctszModelName = TEXT("");
|
|
LPCTSTR lpctszRank0 = TEXT("");
|
|
LPCTSTR lpctszRank1 = TEXT("");
|
|
LPCTSTR lpctszRank2 = TEXT("");
|
|
LPCTSTR lpctszProviderName = TEXT("");
|
|
|
|
BOOL fRet = FALSE;
|
|
const CInfSymbol * pSym=NULL;
|
|
|
|
TCHAR rgchBuf[4098];
|
|
HANDLE hFile=NULL;
|
|
|
|
SYSTEMTIME st;
|
|
UINT u = 0;
|
|
GetLocalTime(&st);
|
|
|
|
// Open file
|
|
{
|
|
TCHAR rgchPathName[MAX_PATH];
|
|
const TCHAR tchBack = (TCHAR) '\\';
|
|
const TCHAR tchColon = (TCHAR) ':';
|
|
const uLen = lstrlen(lpctszIniFile);
|
|
|
|
if (!uLen || (uLen+2) > sizeof(rgchPathName)/sizeof(TCHAR)) goto end;
|
|
|
|
rgchPathName[0] = 0;
|
|
|
|
u=0;
|
|
// Append %windir% if file name is not of the form
|
|
// "\.*" or "?:.*"
|
|
#if 0 // Don't do this anymore.
|
|
if ( (lpctszIniFile[0] != tchBack)
|
|
&& (uLen<2 || lpctszIniFile[1]!=tchColon))
|
|
{
|
|
const UINT uMax = sizeof(rgchPathName)/sizeof(TCHAR) - uLen - 2;
|
|
u = GetWindowsDirectory
|
|
(
|
|
rgchPathName,
|
|
uMax
|
|
);
|
|
|
|
if (!u || u >= uMax) goto end;
|
|
lstrcpy(rgchPathName+u, TEXT("\\"));
|
|
u++;
|
|
}
|
|
#endif // 0
|
|
|
|
ASSERT((u+uLen+1)<(sizeof(rgchPathName)/sizeof(TCHAR)));
|
|
lstrcpy(rgchPathName+u, lpctszIniFile);
|
|
printf("Ini Path Name = [%s]\n", rgchPathName);
|
|
|
|
|
|
// Open file, nuke it if it exists.
|
|
hFile = CreateFile
|
|
(
|
|
rgchPathName,
|
|
GENERIC_WRITE,
|
|
0, // deny sharing
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
|
|
if (hFile==INVALID_HANDLE_VALUE)
|
|
{
|
|
printf("Create file fails with error %08lu\n", GetLastError());
|
|
hFile = NULL;
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
printf("File opened\n");
|
|
}
|
|
}
|
|
|
|
// write header.
|
|
{
|
|
//;
|
|
//; OUT.INF
|
|
//;
|
|
//; Inf generated for a single modem.
|
|
//;
|
|
//; Created: Fri 05-24-1996 12:13:42
|
|
//; Checksum: 12507659
|
|
//; Original Inf: mdmgen.inf/[Rockwell]/%Rockwell1%
|
|
//; Manufacturer: "Rockwell"
|
|
//; Model: "14400 bps PCMCIA Data-Fax Modem"
|
|
//; Rank0ID: GEN_Apex1
|
|
//; Rank1ID: PCMCIA\RIPICAA-RC144ACL-845A
|
|
//; Rank2ID: PCMCIA\RIPICAA-YYY-ZZZ
|
|
//;
|
|
//; Rank0 Version M&M Flags AddReg CopyFile Ranks
|
|
//; SIG= 12342412 12222233 12334444 12234444 12244444 53265123 52366664
|
|
//;
|
|
|
|
const CInfSymbol *pSym = NULL;
|
|
|
|
// File name
|
|
pSym = m_pInfFile->GetFileName();
|
|
lpctszOrigFile = pSym->GetText();
|
|
|
|
// Manufacturer section name
|
|
{
|
|
const CInfManufacturerSection * pManuS =
|
|
m_pManufacturerEntry->GetManufacturerSection();
|
|
if (pManuS)
|
|
{
|
|
pSym = pManuS->GetSectionName();
|
|
lpctszManuS = pSym->GetText();
|
|
}
|
|
}
|
|
|
|
// Model entry name (LHS)
|
|
pSym = m_pModelEntry->GetLHS();
|
|
lpctszModelLHS = pSym->GetText();
|
|
|
|
// Manufacturer name
|
|
pSym = m_pSymManufacturerName;
|
|
lpctszManuName = pSym->GetText();
|
|
|
|
// Model name
|
|
pSym = m_pSymDeviceName;
|
|
lpctszModelName = pSym->GetText();
|
|
|
|
// Rank 0
|
|
pSym = m_pModelEntry->GetRank0ID();
|
|
lpctszRank0 = pSym->GetText();
|
|
|
|
|
|
// Rank 1
|
|
pSym = m_pModelEntry->GetRank1ID();
|
|
lpctszRank1 = pSym->GetText();
|
|
|
|
// Rank 1
|
|
pSym = m_pModelEntry->GetRank1ID();
|
|
lpctszRank1 = pSym->GetText();
|
|
|
|
u = wsprintf
|
|
(
|
|
rgchBuf,
|
|
TEXT
|
|
(
|
|
";\r\n"
|
|
"; OUT.INF\r\n"
|
|
";\r\n"
|
|
"; Inf generated for a single modem.\r\n"
|
|
";\r\n"
|
|
"; Created: %02u-%02u-%04u %02u:%02u:%02u\r\n"
|
|
"; Checksum: %08lx\r\n"
|
|
),
|
|
st.wMonth,
|
|
st.wDay,
|
|
st.wYear,
|
|
st.wHour,
|
|
st.wMinute,
|
|
st.wSecond,
|
|
m_dwSigAll
|
|
);
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"; Original Inf: %s/[%s]/%s\r\n"
|
|
"; Manufacturer: \"%s\"\r\n"
|
|
"; Model: \"%s\"\r\n"
|
|
"; Rank0ID: %s\r\n"
|
|
"; Rank1ID: %s\r\n"
|
|
"; Rank2ID: %s\r\n"
|
|
),
|
|
lpctszOrigFile, // original inf file
|
|
lpctszManuS, // manufacturer section
|
|
lpctszModelLHS, // model entry name
|
|
lpctszManuName, // manufacturer name
|
|
lpctszModelName,// model name
|
|
lpctszRank0, // Rank0 ID
|
|
lpctszRank1, // Rank1 ID
|
|
lpctszRank2 // Rank2 ID
|
|
);
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
";\r\n"
|
|
"; Rank0 Version M&M Flags AddReg CopyFile Dup Ranks\r\n"
|
|
"; SIG= %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\r\n"
|
|
";\r\n"
|
|
),
|
|
m_dwSigRank0,
|
|
m_dwSigVersion,
|
|
m_dwSigManuAndModel,
|
|
m_dwSigFlags,
|
|
m_dwSigAddReg,
|
|
m_dwSigCopyFiles,
|
|
m_dwSigDup, // NoResDup and PosDup
|
|
m_dwSigRanks
|
|
);
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
} // end write header
|
|
|
|
// Write Version
|
|
{
|
|
// Sample:
|
|
//; ---------------------- VERSION ------------------------------
|
|
//[Version]
|
|
//LayoutFile=layout.inf
|
|
//Signature="$CHICAGO$"
|
|
//Class=Modem
|
|
//ClassGUID={4D36E96D-E325-11CE-BFC1-08002BE10318}
|
|
//Provider=%provider%
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ---------------------- VERSION ------------------------------\r\n"
|
|
"[Version]\r\n"
|
|
)
|
|
);
|
|
|
|
// LayoutFile
|
|
pSym = m_pVersion->GetLayoutFile();
|
|
if (pSym)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("LayoutFile=%s\r\n"),
|
|
pSym->GetText()
|
|
);
|
|
}
|
|
|
|
// Signature
|
|
pSym = m_pVersion->GetSignature();
|
|
if (pSym)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("Signature=%s\r\n"),
|
|
pSym->GetText()
|
|
);
|
|
}
|
|
|
|
// Class
|
|
pSym = m_pVersion->GetClass();
|
|
if (pSym)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("Class=%s\r\n"),
|
|
pSym->GetText()
|
|
);
|
|
}
|
|
|
|
// ClassGUID
|
|
pSym = m_pVersion->GetClassGUID();
|
|
if (pSym)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("ClassGUID=%s\r\n"),
|
|
pSym->GetText()
|
|
);
|
|
}
|
|
|
|
// Provider
|
|
pSym = m_pVersion->GetProvider();
|
|
if (pSym)
|
|
{
|
|
lpctszProviderName = pSym->GetText();
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("Provider=%%provider%%\r\n")
|
|
);
|
|
}
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
} // End writing version info
|
|
|
|
|
|
// Write Control flags section
|
|
// Sample:
|
|
// -------------------- CONTROLFLAGS ---------------------------
|
|
// [ControlFlags]
|
|
// ExcludeFromSelect=SERENUM\MNP0281
|
|
// ExcludeFromSelect.NT=LPTENUM\MICROCOMTRAVELPORTE_1FF4
|
|
{
|
|
DWORD dwFlagsAll;
|
|
DWORD dwFlagsNTAll;
|
|
DWORD dwFlagsNTAlpha;
|
|
DWORD dwFlagsNTPPC;
|
|
DWORD dwFlagsNTMips;
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; -------------------- CONTROLFLAGS ---------------------------\r\n"
|
|
"[ControlFlags]\r\n"
|
|
)
|
|
);
|
|
|
|
dwFlagsAll = m_pModelEntry->GetControlFlags(ePLAT_ALL);
|
|
dwFlagsNTAll = m_pModelEntry->GetControlFlags(ePLAT_NT_ALL);
|
|
dwFlagsNTAlpha = m_pModelEntry->GetControlFlags(ePLAT_NT_ALPHA);
|
|
dwFlagsNTPPC = m_pModelEntry->GetControlFlags(ePLAT_NT_PPC);
|
|
dwFlagsNTMips = m_pModelEntry->GetControlFlags(ePLAT_NT_MIPS);
|
|
|
|
if(dwFlagsAll & dwCF_EXCLUDE_FROM_SELECT)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("ExcludeFromSelect=%s\r\n"),
|
|
lpctszRank0
|
|
);
|
|
}
|
|
|
|
if(dwFlagsNTAll & dwCF_EXCLUDE_FROM_SELECT)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("ExcludeFromSelect.NT=%s\r\n"),
|
|
lpctszRank0
|
|
);
|
|
}
|
|
|
|
if(dwFlagsNTAlpha & dwCF_EXCLUDE_FROM_SELECT)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("ExcludeFromSelect.NT.Alpha=%s\r\n"),
|
|
lpctszRank0
|
|
);
|
|
}
|
|
|
|
if(dwFlagsNTPPC & dwCF_EXCLUDE_FROM_SELECT)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("ExcludeFromSelect.NT.PPC=%s\r\n"),
|
|
lpctszRank0
|
|
);
|
|
}
|
|
|
|
if(dwFlagsNTMips & dwCF_EXCLUDE_FROM_SELECT)
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT("ExcludeFromSelect.NT.Mips=%s\r\n"),
|
|
lpctszRank0
|
|
);
|
|
}
|
|
|
|
// TODO: unimplemented: Other control flags.
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
} // End writing control flags section
|
|
|
|
|
|
// Write Manufacturer section
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; -------------------- MANUFACTURER ---------------------------\r\n"
|
|
"[Manufacturer]\r\n"
|
|
"%%make%%= Make\r\n"
|
|
)
|
|
);
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
} // End writing Manufacturer section
|
|
|
|
|
|
// Write make section
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ----------------------- MAKE --------------------------------\r\n"
|
|
"[Make]\r\n"
|
|
"%%model%%= Model, %s"
|
|
),
|
|
lpctszRank0
|
|
);
|
|
if (*lpctszRank1 || *lpctszRank2)
|
|
{
|
|
u+= wsprintf (rgchBuf+u, ", %s", lpctszRank1);
|
|
}
|
|
if (*lpctszRank2)
|
|
{
|
|
u+= wsprintf (rgchBuf+u, ", %s", lpctszRank2);
|
|
}
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
} // End writing make section
|
|
|
|
// Write Model section
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ----------------------- MODEL -------------------------------\r\n"
|
|
"[Model]\r\n"
|
|
"AddReg=AddReg\r\n"
|
|
"CopyFiles=CopyFiles\r\n"
|
|
)
|
|
);
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
} // End writing Model section
|
|
|
|
|
|
// NoResDup section
|
|
{
|
|
// [Make.NoResDup]
|
|
// UNIMODEMCC646872,UNIMODEMA4970248,UNIMODEMB6071C15
|
|
const CInfInstallSection *pInstall = m_pModelEntry->GetInstallSection();
|
|
const CInfList *pSymList = pInstall->GetNoResDupIDList();
|
|
const CInfSymbol *pSym = NULL;
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ---------------------- NORESDUP -----------------------------\r\n"
|
|
"[Model.NoResDup]\r\n"
|
|
)
|
|
);
|
|
|
|
while(pSymList)
|
|
{
|
|
if (pSym) { u+= wsprintf (rgchBuf+u, TEXT(",")); }
|
|
pSym = (const CInfSymbol *) pSymList->GetData();
|
|
u+= wsprintf (rgchBuf+u, TEXT("%s"), pSym->GetText());
|
|
|
|
pSymList = pSymList->Next();
|
|
}
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
}
|
|
|
|
|
|
// PosDup section
|
|
{
|
|
// [Make.PosDup]
|
|
// *PNP0500
|
|
const CInfInstallSection *pInstall = m_pModelEntry->GetInstallSection();
|
|
const CInfList *pSymList = pInstall->GetPosDupIDList();
|
|
const CInfSymbol *pSym = NULL;
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ---------------------- POSDUP -------------------------------\r\n"
|
|
"[Model.PosDup]\r\n"
|
|
)
|
|
);
|
|
|
|
while(pSymList)
|
|
{
|
|
if (pSym) { u+= wsprintf (rgchBuf+u, TEXT(",")); }
|
|
pSym = (const CInfSymbol *) pSymList->GetData();
|
|
u+= wsprintf (rgchBuf+u, TEXT("%s"), pSym->GetText());
|
|
|
|
pSymList = pSymList->Next();
|
|
}
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
}
|
|
|
|
|
|
// Write CopyFiles section
|
|
// BUGBUG: we need the concept of muliple copy-file sections, because
|
|
// each section can have a different destination dir.
|
|
// Also: the CopyFiles.NT, etc sections.
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; --------------------- COPYFILES -----------------------------\r\n"
|
|
"[CopyFiles]\r\n"
|
|
)
|
|
);
|
|
|
|
// Now write each copyfile entry
|
|
{
|
|
const CInfList *pList = m_pCopyFilesList;
|
|
|
|
for (;pList; pList=pList->Next())
|
|
{
|
|
// TODO: unimplemented
|
|
}
|
|
|
|
}
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
|
|
} // End writing CopyFiles section
|
|
|
|
|
|
// Write DestinationDirs section
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ------------------- DESTINATIONDIRS -------------------------\r\n"
|
|
"[DestinationDirs]\r\n"
|
|
)
|
|
);
|
|
|
|
// Now write each copyfile entry
|
|
// TODO: Need to construct destination-dirs entries
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
|
|
} // End writing DestinationDirs section
|
|
|
|
|
|
// TODO: UpdateInis, Uninstall
|
|
|
|
|
|
// Write Addreg section
|
|
{
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ---------------------- ADDREG -------------------------------\r\n"
|
|
"[AddReg]\r\n"
|
|
)
|
|
);
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
|
|
// Now write each addreg entry
|
|
{
|
|
const CInfList *pList = m_pAddRegList;
|
|
|
|
for (;pList; pList=pList->Next())
|
|
{
|
|
LPCTSTR lpctszRegRoot = TEXT("");
|
|
LPCTSTR lpctszSubKey = TEXT("");
|
|
LPCTSTR lpctszValueName = TEXT("");
|
|
TCHAR rgchFlag[20] = TEXT("");
|
|
LPCTSTR lpctszValue = TEXT("");
|
|
DWORD dwFlag = MAXDWORD;
|
|
const CInfSymbol *pSym = NULL;
|
|
const CInfAddRegEntry * pARE =
|
|
(const CInfAddRegEntry *) pList->GetData();
|
|
ASSERT(pARE);
|
|
|
|
pSym = pARE->GetRegRoot();
|
|
lpctszRegRoot = pSym->GetText();
|
|
|
|
pSym = pARE->GetSubKey();
|
|
lpctszSubKey = pSym->GetText();
|
|
|
|
pSym = pARE->GetValueName();
|
|
lpctszValueName = pSym->GetText();
|
|
|
|
dwFlag = pARE->GetFlag();
|
|
if (dwFlag!=MAXDWORD)
|
|
{
|
|
wsprintf(rgchFlag, TEXT("%lu"), dwFlag);
|
|
}
|
|
|
|
pSym = pARE->GetValue();
|
|
lpctszValue = pSym->GetText();
|
|
|
|
//HKR, Settings, Prefix,, "AT"
|
|
//HKR, Responses, "AUTOSTREAM: LEVEL 3", 1, 01, 00, 00,00,00,00, 00,00,00,00
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"%s, %s, %s, %s, %s\r\n"
|
|
),
|
|
lpctszRegRoot,
|
|
lpctszSubKey,
|
|
lpctszValueName,
|
|
rgchFlag,
|
|
lpctszValue
|
|
);
|
|
}
|
|
|
|
}
|
|
} // End writing addreg section
|
|
|
|
|
|
// Write Strings section
|
|
{
|
|
|
|
u+= wsprintf
|
|
(
|
|
rgchBuf+u,
|
|
TEXT
|
|
(
|
|
"\r\n"
|
|
"\r\n"
|
|
"; ---------------------- STRINGS ------------------------------\r\n"
|
|
"[Strings]\r\n"
|
|
"provider=\"%s\"\r\n"
|
|
"make=\"%s\"\r\n"
|
|
"model=\"%s\"\r\n"
|
|
),
|
|
lpctszProviderName,
|
|
lpctszManuName,
|
|
lpctszModelName
|
|
);
|
|
|
|
ASSERT(u < sizeof (rgchBuf)/sizeof(TCHAR));
|
|
|
|
} // End Strings flags section
|
|
|
|
DWORD dwWr;
|
|
if (!WriteFile(hFile, (LPBYTE) rgchBuf, u*sizeof(TCHAR), &dwWr, NULL))
|
|
{
|
|
printf("Write file fails with error %08lu\n", GetLastError());
|
|
goto end;
|
|
}
|
|
else
|
|
{
|
|
printf("Write file succeeded\n");
|
|
}
|
|
|
|
fRet = TRUE;
|
|
|
|
end:
|
|
if (hFile) CloseHandle(hFile);
|
|
|
|
return fRet;
|
|
}
|