From: Rymfax on
I was hoping someone could help me get SetupInstallFromInfSection
working properly. I'm trying to start in install section in a driver
INF (hal.inf specifically). I'm doing this in C#, but I also tried it
in C++ with (MOSTLY) the same
parameters and got the same error, which is 1004 (Invalid Flags).
Here's my C# code that I'm using. Any help would be MOST appreciated.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace UIUHWScan.Classes
public class UpdateHAL
#region Constants

const int INF_STYLE_NONE = 0;
const int INF_STYLE_OLDNT = 1;
const int INF_STYLE_WIN4 = 2;

// Flags for SetupInstallFromInfSection
const uint SPINST_LOGCONFIG =0x00000001;
const uint SPINST_INIFILES = 0x00000002;
const uint SPINST_REGISTRY = 0x00000004;
const uint SPINST_INI2REG = 0x00000008;
const uint SPINST_FILES = 0x00000010;
const uint SPINST_BITREG = 0x00000020;
const uint SPINST_REGSVR = 0x00000040;
const uint SPINST_UNREGSVR = 0x00000080;
const uint SPINST_PROFILEITEMS = 0x00000100;

const uint SPINST_COPYINF = 0x00000200;
const uint SPINST_ALL = 0x000003ff;

const uint SPINST_SINGLESECTION = 0x00010000;
const uint SPINST_LOGCONFIG_IS_FORCED = 0x00020000;
const uint SPINST_LOGCONFIGS_ARE_OVERRIDES = 0x00040000;
const uint SPINST_DEVICEINSTALL = 0x00100000;

// CopyStyle values for copy and queue-related APIs
const uint SP_COPY_DELETESOURCE = 0x0000001; // delete
source file on successful copy
const uint SP_COPY_REPLACEONLY = 0x0000002; // copy only if
target file already present
const uint SP_COPY_NEWER = 0x0000004; // copy only if source
newer than or same as target
const uint SP_COPY_NOOVERWRITE = 0x0000008; // copy only if
target doesn't exist
const uint SP_COPY_NODECOMP = 0x0000010; // don't decompress
source file while copying
const uint SP_COPY_LANGUAGEAWARE = 0x0000020; // don't
overwrite file of different language
const uint SP_COPY_SOURCE_ABSOLUTE = 0x0000040; //
SourceFile is a full source path
const uint SP_COPY_SOURCEPATH_ABSOLUTE = 0x0000080; //
SourcePathRoot is the full path
const uint SP_COPY_IN_USE_NEEDS_REBOOT = 0x0000100; //
System needs reboot if file in use
const uint SP_COPY_FORCE_IN_USE = 0x0000200; // Force target-
in-use behavior
const uint SP_COPY_NOSKIP = 0x0000400; // Skip is disallowed
for this file or section
const uint SP_FLAG_CABINETCONTINUATION = 0x0000800; // Used
with need media notification
const uint SP_COPY_FORCE_NOOVERWRITE = 0x0001000; // like
NOOVERWRITE but no callback nofitication
const uint SP_COPY_FORCE_NEWER = 0x0002000; // like NEWER
but no callback nofitication
const uint SP_COPY_WARNIFSKIP = 0x0004000; // system
critical file: warn if user tries to skip
const uint SP_COPY_NOBROWSE = 0x0008000; // Browsing is
disallowed for this file or section
const uint SP_COPY_NEWER_ONLY = 0x0010000; // copy only if
source file newer than target
const uint SP_COPY_RESERVED = 0x0020000; // was:
const uint SP_COPY_OEMINF_CATALOG_ONLY = 0x0040000; //
(SetupCopyOEMInf only) don't copy INF--just catalog
const uint SP_COPY_REPLACE_BOOT_FILE = 0x0080000; // file
must be present upon reboot (i.e., it's
// needed by
the loader); this flag implies a reboot

const long HKEY_LOCAL_MACHINE = 0x80000002L;

// Operation/queue start/end notification. These are ordinal
const uint SPFILENOTIFY_STARTQUEUE =0x00000001;
const uint SPFILENOTIFY_ENDQUEUE =0x00000002;
const uint SPFILENOTIFY_STARTSUBQUEUE =0x00000003;
const uint SPFILENOTIFY_ENDSUBQUEUE =0x00000004;
const uint SPFILENOTIFY_STARTDELETE =0x00000005;
const uint SPFILENOTIFY_ENDDELETE =0x00000006;
const uint SPFILENOTIFY_DELETEERROR =0x00000007;
const uint SPFILENOTIFY_STARTRENAME =0x00000008;
const uint SPFILENOTIFY_ENDRENAME =0x00000009;
const uint SPFILENOTIFY_RENAMEERROR =0x0000000a;
const uint SPFILENOTIFY_STARTCOPY =0x0000000b;
const uint SPFILENOTIFY_ENDCOPY =0x0000000c;
const uint SPFILENOTIFY_COPYERROR =0x0000000d;
const uint SPFILENOTIFY_NEEDMEDIA =0x0000000e;
const uint SPFILENOTIFY_QUEUESCAN = 0x0000000f;

const uint SPFILENOTIFY_FILEINCABINET = 0x00000011; // The
file has been extracted from the cabinet.
const uint SPFILENOTIFY_NEEDNEWCABINET = 0x00000012; // file
is encountered in the cabinet.
const uint SPFILENOTIFY_FILEEXTRACTED = 0x00000013; // The
current file is continued in the next cabinet.
const uint NO_ERROR = 0;


#region Delegates

public delegate uint PSP_FILE_CALLBACK(uint context, uint
IntPtr param1, IntPtr param2);


#region DLL Imports

[DllImport("setupapi.dll", SetLastError = true, CharSet =
private static extern bool SetupInstallFromInfSection(IntPtr
IntPtr infHandle, string sectionName, uint flags, IntPtr
IntPtr sourceRootPath, uint copyFlags, PSP_FILE_CALLBACK
ref uint context, IntPtr deviceInfoSet, IntPtr

[DllImport("setupapi.dll", SetLastError = true)]
public static extern IntPtr SetupOpenInfFile(
string FileName,
IntPtr InfClass,
int InfStyle,
int ErrorLine

[DllImport("setupapi.dll", SetLastError = true)]
public static extern void SetupCloseInfFile(
IntPtr InfHandle


/// <summary>
/// The FileCallback callback function is used by a number of
the setup functions. The PSP_FILE_CALLBACK type defines a pointer to
this callback function. FileCallback is a placeholder for the
application-defined function name.
/// Platform SDK: Setup API
/// </summary>
private uint CallBack(uint context, uint notification, IntPtr
param1, IntPtr param2)
uint rtnValue = NO_ERROR;
Console.WriteLine("CallBack: Context = {0}, Notifacation =
context, notification);
return rtnValue;

public bool InstallSection()
string windowsFolder =
string halINF = Path.Combine(windowsFolder, @"inf
IntPtr hInf = SetupOpenInfFile(halINF, IntPtr.Zero,
if (hInf == (IntPtr)(-1))
int err = Marshal.GetLastWin32Error();
Console.WriteLine("Invalid INF File: {0}", halINF);
return false;
string installSection = "E_ISA_UP_HAL";
bool iResult = false;
PSP_FILE_CALLBACK callback = new
uint context = 0;
SetupInstallFromInfSection(IntPtr.Zero, hInf,
IntPtr((int)HKEY_LOCAL_MACHINE), IntPtr.Zero,
SP_COPY_FORCE_IN_USE, callback, ref context,
IntPtr.Zero, IntPtr.Zero);
if (!iResult)
int err = Marshal.GetLastWin32Error();
Console.WriteLine("Error : {0}",
return false;

return true;

From: Tim Roberts on
Rymfax <cwalker(a)> wrote:
>I was hoping someone could help me get SetupInstallFromInfSection
>working properly. I'm trying to start in install section in a driver
>INF (hal.inf specifically).

What's the point of this? If you have an EISA machine, this should be done
automatically. If not, what good is it going to do to install an EISA
Tim Roberts, timr(a)
Providenza & Boekelheide, Inc.