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.
627 lines
16 KiB
627 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
infload.h
|
|
|
|
Abstract:
|
|
|
|
Private header file for internal inf routines.
|
|
|
|
Author:
|
|
|
|
Ted Miller (tedm) 19-Jan-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
//
|
|
// Define maximum string sizes allowed in INFs.
|
|
//
|
|
#define MAX_STRING_LENGTH 511 // this is the maximum size of an unsubstituted string
|
|
#define MAX_SECT_NAME_LEN 255
|
|
#if MAX_SECT_NAME_LEN > MAX_STRING_LENGTH
|
|
#error MAX_SECT_NAME_LEN is too large!
|
|
#endif
|
|
|
|
|
|
#include "pshpack1.h"
|
|
|
|
//
|
|
// Make absolutely sure that these structures are DWORD aligned
|
|
// because we turn alignment off, to make sure sdtructures are
|
|
// packed as tightly as possible into memory blocks.
|
|
//
|
|
|
|
//
|
|
// Internal representation of a section in an inf file
|
|
//
|
|
typedef struct _INF_LINE {
|
|
|
|
//
|
|
// Number of values on the line
|
|
// This includes the key if Flags has INF_LINE_HASKEY
|
|
// (In that case the first two entries in the Values array
|
|
// contain the key--the first one in case-insensitive form used
|
|
// for lookup, and the second in case-sensitive form for display.
|
|
// INF lines with a single value (no key) are treated the same way.)
|
|
// Otherwise the first entry in the Values array is the first
|
|
// value on the line
|
|
//
|
|
WORD ValueCount;
|
|
WORD Flags;
|
|
|
|
//
|
|
// String IDs for the values on the line.
|
|
// The values are stored in the value block,
|
|
// one after another.
|
|
//
|
|
// The value is the offset within the value block as opposed to
|
|
// an actual pointer. We do this because the value block gets
|
|
// reallocated as the inf file is loaded.
|
|
//
|
|
UINT Values;
|
|
|
|
} INF_LINE, *PINF_LINE;
|
|
|
|
//
|
|
// INF_LINE.Flags
|
|
//
|
|
#define INF_LINE_HASKEY 0x0000001
|
|
#define INF_LINE_SEARCHABLE 0x0000002
|
|
|
|
#define HASKEY(Line) ((Line)->Flags & INF_LINE_HASKEY)
|
|
#define ISSEARCHABLE(Line) ((Line)->Flags & INF_LINE_SEARCHABLE)
|
|
|
|
//
|
|
// INF section
|
|
// This guy is kept separate and has a pointer to the actual data
|
|
// to make sorting the sections a little easier
|
|
//
|
|
typedef struct _INF_SECTION {
|
|
//
|
|
// String Table ID of the name of the section
|
|
//
|
|
LONG SectionName;
|
|
|
|
//
|
|
// Number of lines in this section
|
|
//
|
|
DWORD LineCount;
|
|
|
|
//
|
|
// The section's lines. The line structures are stored packed
|
|
// in the line block, one after another.
|
|
//
|
|
// The value is the offset within the line block as opposed to
|
|
// an actual pointer. We do it this way because the line block
|
|
// gets reallocated as the inf file is loaded.
|
|
//
|
|
UINT Lines;
|
|
|
|
} INF_SECTION, *PINF_SECTION;
|
|
|
|
#include "poppack.h"
|
|
|
|
//
|
|
// Define structures for user-defined DIRID storage.
|
|
//
|
|
typedef struct _USERDIRID {
|
|
UINT Id;
|
|
TCHAR Directory[MAX_PATH];
|
|
} USERDIRID, *PUSERDIRID;
|
|
|
|
typedef struct _USERDIRID_LIST {
|
|
PUSERDIRID UserDirIds; // may be NULL
|
|
UINT UserDirIdCount;
|
|
} USERDIRID_LIST, *PUSERDIRID_LIST;
|
|
|
|
typedef struct _STRINGSUBST_NODE {
|
|
UINT ValueOffset;
|
|
LONG TemplateStringId;
|
|
BOOL CaseSensitive;
|
|
} STRINGSUBST_NODE, *PSTRINGSUBST_NODE;
|
|
|
|
|
|
//
|
|
// Version block structure that is stored (packed) in the opaque
|
|
// VersionData buffer of a caller-supplied SP_INF_INFORMATION structure.
|
|
//
|
|
typedef struct _INF_VERSION_BLOCK {
|
|
UINT NextOffset;
|
|
FILETIME LastWriteTime;
|
|
WORD DatumCount;
|
|
WORD OffsetToData; // offset (in bytes) from beginning of Filename buffer.
|
|
UINT DataSize; // DataSize and TotalSize are both byte counts.
|
|
UINT TotalSize;
|
|
TCHAR Filename[ANYSIZE_ARRAY];
|
|
//
|
|
// Data follows Filename in the buffer
|
|
//
|
|
} INF_VERSION_BLOCK, *PINF_VERSION_BLOCK;
|
|
|
|
//
|
|
// Internal version block node.
|
|
//
|
|
typedef struct _INF_VERSION_NODE {
|
|
FILETIME LastWriteTime;
|
|
UINT FilenameSize;
|
|
CONST TCHAR *DataBlock;
|
|
UINT DataSize;
|
|
WORD DatumCount;
|
|
TCHAR Filename[MAX_PATH];
|
|
} INF_VERSION_NODE, *PINF_VERSION_NODE;
|
|
|
|
//
|
|
// Internal representation of an inf file.
|
|
//
|
|
typedef struct _LOADED_INF {
|
|
DWORD Signature;
|
|
|
|
//
|
|
// The following 3 fields are used for precompiled INFs (PNF).
|
|
// If FileHandle is not INVALID_HANDLE_VALUE, then this is a PNF,
|
|
// and the MappingHandle and ViewAddress fields are also valid.
|
|
// Otherwise, this is a plain old in-memory INF.
|
|
//
|
|
HANDLE FileHandle;
|
|
HANDLE MappingHandle;
|
|
PVOID ViewAddress;
|
|
|
|
PVOID StringTable;
|
|
DWORD SectionCount;
|
|
PINF_SECTION SectionBlock;
|
|
PINF_LINE LineBlock;
|
|
PLONG ValueBlock;
|
|
INF_VERSION_NODE VersionBlock;
|
|
BOOL HasStrings;
|
|
|
|
//
|
|
// If this INF contains any DIRID references to the system partition, then
|
|
// store the OsLoader path that was used when compiling this INF here. (This
|
|
// value will always be correct when the INF is loaded. However, if drive letters
|
|
// are subsequently reassigned, then it will be incorrect until the INF is unloaded
|
|
// and re-loaded.)
|
|
//
|
|
PCTSTR OsLoaderPath; // may be NULL
|
|
|
|
//
|
|
// Remember the OEM path where this INF originally came from.
|
|
//
|
|
PCTSTR InfSourcePath; // may be NULL
|
|
|
|
//
|
|
// Maintain a list of value offsets that require string substitution at
|
|
// run-time.
|
|
//
|
|
PSTRINGSUBST_NODE SubstValueList; // may be NULL
|
|
WORD SubstValueCount;
|
|
|
|
//
|
|
// Place the style WORD here (immediately following another WORD field),
|
|
// to fill a single DWORD.
|
|
//
|
|
WORD Style; // INF_STYLE_OLDNT, INF_STYLE_WIN4
|
|
|
|
//
|
|
// Sizes in bytes of various buffers
|
|
//
|
|
UINT SectionBlockSizeBytes;
|
|
UINT LineBlockSizeBytes;
|
|
UINT ValueBlockSizeBytes;
|
|
|
|
//
|
|
// Embedded structure containing information about the current user-defined
|
|
// DIRID values.
|
|
//
|
|
USERDIRID_LIST UserDirIdList;
|
|
|
|
//
|
|
// Synchronization.
|
|
//
|
|
MYLOCK Lock;
|
|
|
|
//
|
|
// INFs are append-loaded via a doubly-linked list of LOADED_INFs.
|
|
// (list is not circular--Prev of head is NULL, Next of tail is NULL)
|
|
//
|
|
struct _LOADED_INF *Prev;
|
|
struct _LOADED_INF *Next;
|
|
|
|
} LOADED_INF, *PLOADED_INF;
|
|
|
|
#define LOADED_INF_SIG 0x24666e49 // Inf$
|
|
|
|
#define LockInf(Inf) BeginSynchronizedAccess(&(Inf)->Lock)
|
|
#define UnlockInf(Inf) EndSynchronizedAccess(&(Inf)->Lock)
|
|
|
|
//
|
|
// Helper define
|
|
//
|
|
#define INF_STYLE_ALL (INF_STYLE_WIN4 | INF_STYLE_OLDNT)
|
|
|
|
|
|
//
|
|
// Define file header structure for precompiled INF (.PNF).
|
|
//
|
|
typedef struct _PNF_HEADER {
|
|
|
|
WORD Version; // HiByte - Major Ver#, LoByte - Minor Ver#
|
|
WORD InfStyle;
|
|
DWORD Flags;
|
|
|
|
DWORD InfSubstValueListOffset;
|
|
WORD InfSubstValueCount;
|
|
|
|
WORD InfVersionDatumCount;
|
|
DWORD InfVersionDataSize;
|
|
DWORD InfVersionDataOffset;
|
|
FILETIME InfVersionLastWriteTime;
|
|
|
|
DWORD StringTableBlockOffset;
|
|
DWORD StringTableBlockSize;
|
|
|
|
DWORD InfSectionCount;
|
|
DWORD InfSectionBlockOffset;
|
|
DWORD InfSectionBlockSize;
|
|
DWORD InfLineBlockOffset;
|
|
DWORD InfLineBlockSize;
|
|
DWORD InfValueBlockOffset;
|
|
DWORD InfValueBlockSize;
|
|
|
|
DWORD WinDirPathOffset;
|
|
DWORD OsLoaderPathOffset;
|
|
|
|
WORD StringTableHashBucketCount;
|
|
|
|
WORD wReserved;
|
|
|
|
DWORD InfSourcePathOffset; // may be 0
|
|
|
|
DWORD dwReserved;
|
|
|
|
} PNF_HEADER, *PPNF_HEADER;
|
|
|
|
//
|
|
// Define Major and Minor versions of the PNF format (currently 1.1)
|
|
//
|
|
#define PNF_MAJOR_VERSION (0x01)
|
|
#define PNF_MINOR_VERSION (0x01)
|
|
|
|
//
|
|
// Define flag values for the PNF header's Flags field.
|
|
//
|
|
#define PNF_FLAG_IS_UNICODE (0x00000001)
|
|
#define PNF_FLAG_HAS_STRINGS (0x00000002)
|
|
|
|
//
|
|
// Define our string table hash bucket count here, since this number is stored
|
|
// in the PNF header and validated against at load time.
|
|
//
|
|
#define HASH_BUCKET_COUNT 509
|
|
|
|
|
|
//
|
|
// Public inf functions in infload.c. All other routines are private to
|
|
// the inf handler package.
|
|
//
|
|
DWORD
|
|
DetermineInfStyle(
|
|
IN PCTSTR Filename,
|
|
IN LPWIN32_FIND_DATA FindData
|
|
);
|
|
|
|
//
|
|
// Flags for LoadInfFile.
|
|
//
|
|
#define LDINF_FLAG_MATCH_CLASS_GUID (0x00000001)
|
|
#define LDINF_FLAG_ALWAYS_TRY_PNF (0x00000002)
|
|
#define LDINF_FLAG_IGNORE_SYSPART (0x00000004)
|
|
|
|
DWORD
|
|
LoadInfFile(
|
|
IN PCTSTR Filename,
|
|
IN LPWIN32_FIND_DATA FileData,
|
|
IN DWORD Style,
|
|
IN DWORD Flags,
|
|
IN PCTSTR ClassGuidString, OPTIONAL
|
|
IN PCTSTR InfSourcePath, OPTIONAL
|
|
IN PLOADED_INF AppendInf, OPTIONAL
|
|
OUT PLOADED_INF *LoadedInf,
|
|
OUT UINT *ErrorLineNumber
|
|
);
|
|
|
|
VOID
|
|
FreeInfFile(
|
|
IN PLOADED_INF LoadedInf
|
|
);
|
|
|
|
|
|
//
|
|
// Global strings used throughout the inf loaders/runtime stuff. Sizes are
|
|
// included so that we can do sizeof() instead of lstrlen() to determine string
|
|
// length.
|
|
//
|
|
// The content of the following strings is defined in infstr.h:
|
|
//
|
|
extern CONST TCHAR pszSignature[SIZECHARS(INFSTR_KEY_SIGNATURE)],
|
|
pszVersion[SIZECHARS(INFSTR_SECT_VERSION)],
|
|
pszClass[SIZECHARS(INFSTR_KEY_HARDWARE_CLASS)],
|
|
pszClassGuid[SIZECHARS(INFSTR_KEY_HARDWARE_CLASSGUID)],
|
|
pszProvider[SIZECHARS(INFSTR_KEY_PROVIDER)],
|
|
pszStrings[SIZECHARS(SZ_KEY_STRINGS)],
|
|
pszLayoutFile[SIZECHARS(SZ_KEY_LAYOUT_FILE)],
|
|
pszManufacturer[SIZECHARS(INFSTR_SECT_MFG)],
|
|
pszControlFlags[SIZECHARS(INFSTR_CONTROLFLAGS_SECTION)],
|
|
pszSourceDisksNames[SIZECHARS(SZ_KEY_SRCDISKNAMES)],
|
|
pszSourceDisksFiles[SIZECHARS(SZ_KEY_SRCDISKFILES)],
|
|
pszDestinationDirs[SIZECHARS(SZ_KEY_DESTDIRS)],
|
|
pszDefaultDestDir[SIZECHARS(SZ_KEY_DEFDESTDIR)],
|
|
pszReboot[SIZECHARS(INFSTR_REBOOT)],
|
|
pszRestart[SIZECHARS(INFSTR_RESTART)],
|
|
pszClassInstall32[SIZECHARS(INFSTR_SECT_CLASS_INSTALL_32)];
|
|
|
|
//
|
|
// Other misc. global strings:
|
|
//
|
|
#define DISTR_INF_DRVDESCFMT (TEXT("%s.") INFSTR_STRKEY_DRVDESC)
|
|
#define DISTR_INF_HWSECTIONFMT (TEXT("%s.") INFSTR_SUBKEY_HW)
|
|
#define DISTR_INF_CHICAGOSIG (TEXT("$Chicago$"))
|
|
#define DISTR_INF_WINNTSIG (TEXT("$Windows NT$"))
|
|
#define DISTR_INF_WIN95SIG (TEXT("$Windows 95$"))
|
|
#define DISTR_INF_WIN_SUFFIX (TEXT(".") INFSTR_PLATFORM_WIN)
|
|
#define DISTR_INF_NT_SUFFIX (TEXT(".") INFSTR_PLATFORM_NT)
|
|
#define DISTR_INF_PNF_SUFFIX (TEXT(".PNF"))
|
|
#define DISTR_INF_SERVICES_SUFFIX (TEXT(".") INFSTR_SUBKEY_SERVICES)
|
|
|
|
//
|
|
// Define platform suffix string based upon architecture being compiled for.
|
|
//
|
|
#if defined(_ALPHA_)
|
|
|
|
#define DISTR_INF_NTPLATFORM_SUFFIX (TEXT(".") INFSTR_PLATFORM_NTALPHA)
|
|
|
|
#elif defined(_MIPS_)
|
|
|
|
#define DISTR_INF_NTPLATFORM_SUFFIX (TEXT(".") INFSTR_PLATFORM_NTMIPS)
|
|
|
|
#elif defined(_PPC_)
|
|
|
|
#define DISTR_INF_NTPLATFORM_SUFFIX (TEXT(".") INFSTR_PLATFORM_NTPPC)
|
|
|
|
#elif defined(_X86_)
|
|
|
|
#define DISTR_INF_NTPLATFORM_SUFFIX (TEXT(".") INFSTR_PLATFORM_NTX86)
|
|
|
|
#else
|
|
|
|
#error Unknown processor type
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// (Sizes are included for all strings that we define privately. This
|
|
// is done so that we can do sizeof() instead of lstrlen() to determine
|
|
// string length. Keep in sync with definitions in infload.c!)
|
|
//
|
|
extern CONST TCHAR pszDrvDescFormat[SIZECHARS(DISTR_INF_DRVDESCFMT)],
|
|
pszHwSectionFormat[SIZECHARS(DISTR_INF_HWSECTIONFMT)],
|
|
pszChicagoSig[SIZECHARS(DISTR_INF_CHICAGOSIG)],
|
|
pszWindowsNTSig[SIZECHARS(DISTR_INF_WINNTSIG)],
|
|
pszWindows95Sig[SIZECHARS(DISTR_INF_WIN95SIG)],
|
|
pszWinSuffix[SIZECHARS(DISTR_INF_WIN_SUFFIX)],
|
|
pszNtSuffix[SIZECHARS(DISTR_INF_NT_SUFFIX)],
|
|
pszNtPlatformSuffix[SIZECHARS(DISTR_INF_NTPLATFORM_SUFFIX)],
|
|
pszPnfSuffix[SIZECHARS(DISTR_INF_PNF_SUFFIX)],
|
|
pszServicesSectionSuffix[SIZECHARS(DISTR_INF_SERVICES_SUFFIX)];
|
|
|
|
//
|
|
// Define a (non-CONST) array of strings that specifies what lines to look for
|
|
// in an INF's [ControlFlags] section when determining whether a particular device
|
|
// ID should be excluded. This is filled in during process attach for speed
|
|
// reasons.
|
|
//
|
|
// The max string length (including NULL) is 32, and there can be a maximum of 3
|
|
// such strings. E.g.: ExcludeFromSelect, ExcludeFromSelect.NT, ExcludeFromSelect.NTAlpha
|
|
//
|
|
extern TCHAR pszExcludeFromSelectList[3][32];
|
|
extern DWORD ExcludeFromSelectListUb; // contains the number of strings in the above list (2 or 3).
|
|
|
|
|
|
//
|
|
// Routine to determine whether a character is whitespace.
|
|
//
|
|
BOOL
|
|
IsWhitespace(
|
|
IN PCTSTR pc
|
|
);
|
|
|
|
//
|
|
// Routine to skip whitespace (but not newlines)
|
|
//
|
|
VOID
|
|
SkipWhitespace(
|
|
IN OUT PCTSTR *Location,
|
|
IN PCTSTR BufferEnd
|
|
);
|
|
|
|
PINF_SECTION
|
|
InfLocateSection(
|
|
IN PLOADED_INF Inf,
|
|
IN PCTSTR SectionName,
|
|
OUT PUINT SectionNumber OPTIONAL
|
|
);
|
|
|
|
BOOL
|
|
InfLocateLine(
|
|
IN PLOADED_INF Inf,
|
|
IN PINF_SECTION Section,
|
|
IN PCTSTR Key, OPTIONAL
|
|
IN OUT PUINT LineNumber,
|
|
OUT PINF_LINE *Line
|
|
);
|
|
|
|
PTSTR
|
|
InfGetKeyOrValue(
|
|
IN PLOADED_INF Inf,
|
|
IN PCTSTR SectionName,
|
|
IN PCTSTR LineKey, OPTIONAL
|
|
IN UINT LineNumber, OPTIONAL
|
|
IN UINT ValueNumber,
|
|
OUT PLONG StringId OPTIONAL
|
|
);
|
|
|
|
PTSTR
|
|
InfGetField(
|
|
IN PLOADED_INF Inf,
|
|
IN PINF_LINE InfLine,
|
|
IN UINT ValueNumber,
|
|
OUT PLONG StringId OPTIONAL
|
|
);
|
|
|
|
PINF_LINE
|
|
InfLineFromContext(
|
|
IN PINFCONTEXT Context
|
|
);
|
|
|
|
//
|
|
// Define a macro to retrieve the case-insensitive (i.e., searchable) string ID
|
|
// for an INF line's key, or -1 if there is no key.
|
|
// NOTE: INF lock must have been acquired before calling this macro!
|
|
//
|
|
// LONG
|
|
// pInfGetLineKeyId(
|
|
// IN PLOADED_INF Inf,
|
|
// IN PINF_LINE InfLine
|
|
// )
|
|
//
|
|
#define pInfGetLineKeyId(Inf,InfLine) (ISSEARCHABLE(InfLine) ? (Inf)->ValueBlock[(InfLine)->Values] : -1)
|
|
|
|
//
|
|
// Routine to allocate and initialize a loaded inf descriptor.
|
|
//
|
|
PLOADED_INF
|
|
AllocateLoadedInfDescriptor(
|
|
IN DWORD SectionBlockSize,
|
|
IN DWORD LineBlockSize,
|
|
IN DWORD ValueBlockSize
|
|
);
|
|
|
|
VOID
|
|
FreeInfOrPnfStructures(
|
|
IN PLOADED_INF Inf
|
|
);
|
|
|
|
//
|
|
// Define a macro to free all memory blocks associated with a loaded INF or PNF,
|
|
// and then free the memory for the loaded INF structure itself
|
|
//
|
|
// VOID
|
|
// FreeLoadedInfDescriptor(
|
|
// IN PLOADED_INF Inf
|
|
// );
|
|
//
|
|
#define FreeLoadedInfDescriptor(Inf) { \
|
|
FreeInfOrPnfStructures(Inf); \
|
|
MyFree(Inf); \
|
|
}
|
|
|
|
BOOL
|
|
AddDatumToVersionBlock(
|
|
IN OUT PINF_VERSION_NODE VersionNode,
|
|
IN PCTSTR DatumName,
|
|
IN PCTSTR DatumValue
|
|
);
|
|
|
|
//
|
|
// Old inf manipulation routines, called by new inf loader
|
|
//
|
|
DWORD
|
|
ParseOldInf(
|
|
IN PCTSTR FileImage,
|
|
IN DWORD FileImageSize,
|
|
OUT PLOADED_INF *Inf,
|
|
OUT UINT *ErrorLineNumber
|
|
);
|
|
|
|
DWORD
|
|
ProcessOldInfVersionBlock(
|
|
IN PLOADED_INF Inf
|
|
);
|
|
|
|
//
|
|
// Run-time helper routines.
|
|
//
|
|
PCTSTR
|
|
pSetupFilenameFromLine(
|
|
IN PINFCONTEXT Context,
|
|
IN BOOL GetSourceName
|
|
);
|
|
|
|
|
|
//
|
|
// Logical configuration stuff, inflogcf.c
|
|
//
|
|
DWORD
|
|
pSetupInstallLogConfig(
|
|
IN HINF Inf,
|
|
IN PCTSTR SectionName,
|
|
IN DEVINST DevInst
|
|
);
|
|
|
|
//
|
|
// INF Version information retrieval
|
|
//
|
|
PCTSTR
|
|
pSetupGetVersionDatum(
|
|
IN PINF_VERSION_NODE VersionNode,
|
|
IN PCTSTR DatumName
|
|
);
|
|
|
|
|
|
//
|
|
// Private installation routines.
|
|
//
|
|
BOOL
|
|
_SetupInstallFromInfSection(
|
|
IN HWND Owner, OPTIONAL
|
|
IN HINF InfHandle,
|
|
IN PCTSTR SectionName,
|
|
IN UINT Flags,
|
|
IN HKEY RelativeKeyRoot, OPTIONAL
|
|
IN PCTSTR SourceRootPath, OPTIONAL
|
|
IN UINT CopyFlags,
|
|
IN PVOID MsgHandler,
|
|
IN PVOID Context, OPTIONAL
|
|
IN HDEVINFO DeviceInfoSet, OPTIONAL
|
|
IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
|
|
IN BOOL IsMsgHandlerNativeCharWidth
|
|
);
|
|
|
|
DWORD
|
|
pSetupInstallFiles(
|
|
IN HINF Inf,
|
|
IN HINF LayoutInf, OPTIONAL
|
|
IN PCTSTR SectionName,
|
|
IN PCTSTR SourceRootPath, OPTIONAL
|
|
IN PSP_FILE_CALLBACK MsgHandler, OPTIONAL
|
|
IN PVOID Context, OPTIONAL
|
|
IN UINT CopyStyle,
|
|
IN HWND Owner, OPTIONAL
|
|
IN HSPFILEQ UserFileQ, OPTIONAL
|
|
IN BOOL IsMsgHandlerNativeCharWidth
|
|
);
|
|
|
|
DWORD
|
|
pSetupInstallRegistry(
|
|
IN HINF Inf,
|
|
IN PCTSTR SectionName,
|
|
IN HKEY UserRootKey,
|
|
IN DEVINST DevInst OPTIONAL
|
|
);
|
|
|