Jump to content

Is it possible in conjunction with SETUPCOPYOEM.EXE?


donjuan

Recommended Posts

Hi all,

I'll ask directly.Is it possible to pre-copy the inf files which are in driverpacks (7zipped or else doesnt matter) to windows/inf folder and again pre-add those inf entries into the registry just before setup ends by a prepared silent winrar sfx ? The reason why I am asking this is that, everytime ı install windows to a system, it takes so much time to integrate the infs to the installation and setupcopyoeminf.exe integrates every inf file one by one very very slowly.

I mean it would be great if we can prepare a winrar silent sfx so to install these infs quickly and silently and add the registry entries as needed.By the way, I know that everytime I change my driverpack content, I must re-prepare this winrar sfx again but I only want to know is it enough only to put the oem infs and reg entries and add the sfx comment? Or should I first make a virtual pc clean installation and then after setup, gather all infs, Or should I just gather the infs from the driverpacks directly?

Plase I wanna decrease the time of my setup and want also all the drivers recognized and integrated after windows windows setup.

Thanks in advance..

Link to comment
Share on other sites


You may want to check out a little project I started that addresses this issue. I originally made this with idea of having it run from RunOnceEx, which is does, but I discovered just today that it's pretty adaptable to pre-existing installs.

I did a full reinstall on my wife's laptop about a month ago, and just today I decided to try this out and worked perfectly. My method does not use setupcopyoeminf.exe. Instead I simply copy over the drivers to %SystemRoot%\D and run SetDevicePath.exe against that directory. The script will even cab up the compressable files if you want.

One benefit is that you can easily come back to the computer a month or however long later, delete the driver directory, run my script again and you'll now have builtin support for the latest drivers. I'm not too comfortable with the way that setupcopyoeminf.exe works so I came up with this method.

Link to comment
Share on other sites

@RogueSpear

You may want to check out a little project I started that addresses this issue. I originally made this with idea of having it run from RunOnceEx, which is does, but I discovered just today that it's pretty adaptable to pre-existing installs.

I did a full reinstall on my wife's laptop about a month ago, and just today I decided to try this out and worked perfectly. My method does not use setupcopyoeminf.exe. Instead I simply copy over the drivers to %SystemRoot%\D and run SetDevicePath.exe against that directory. The script will even cab up the compressable files if you want.

One benefit is that you can easily come back to the computer a month or however long later, delete the driver directory, run my script again and you'll now have builtin support for the latest drivers. I'm not too comfortable with the way that setupcopyoeminf.exe works so I came up with this method.

Thanks for the info and forwarding me to to your page.I believe your script is useful and I will try to use it in the future but my point was to pre-copy especially the pnf files, which I suppose includes the path information to the drivers.Let me explain more precisely;

For example, suppose I have my drivers in c:\windows\d folder, precopied by windows setup.At the end of setup I do not want to use setupcopyoeminf.exe because it takes so much time.And for this reason I setup windows to a virtual machine and setupcopyoeminf.exe does its job for me for once.And after that I figure out the oem<sequence number>.inf and oem<sequencenumber>.pnf files and prepare a silent sfx so that instead of setupcopyoeminf.exe, it extracts all the pnf and inf files to windows\inf dir.

My point is exactly as above.

Link to comment
Share on other sites

I really forsee some problems with that method. I'm not really expert enough on the procedure that setupcopyoeminf.exe goes through. The procedure that my script goes through definately works, as I have tested it extensively. Also it's very easy to update a computer to a newer set of drivers if you ever wanted to and very easy to select exactly which drivers you want to keep. Lastly, while it may take a little more hard drive space, it's a relatively simple method that has not failed me yet, the integration is extremely fast from a Method 1 source and acceptable from a Method 2 source.

One of the problems I have with setupcopyoeminf.exe is recovering from it. It doesn't seem so easily reversed.

Link to comment
Share on other sites

Thanks for the info and forwarding me to to your page.I believe your script is useful and I will try to use it in the future but my point was to pre-copy especially the pnf files, which I suppose includes the path information to the drivers.Let me explain more precisely;

For example, suppose I have my drivers in c:\windows\d folder, precopied by windows setup.At the end of setup I do not want to use setupcopyoeminf.exe because it takes so much time.And for this reason I setup windows to a virtual machine and setupcopyoeminf.exe does its job for me for once.And after that I figure out the oem<sequence number>.inf and oem<sequencenumber>.pnf files and prepare a silent sfx so that instead of setupcopyoeminf.exe, it extracts all the pnf and inf files to windows\inf dir.

It might work, however you will not have the .cat files (driver signature) in your %windir%\system32\CatRoot\{GUID} directory and there will be errors in %windir%\setupapi.log, because the API call SetupCopyOEMInf (that's why this tool has its strange name :) ) in setupapi.dll is one of the few official and supported ways to properly integrate a driver in Windows 2K/XP/2K3. Simply copying oem<number>.INF/oem<number>.PNF/oem<number>.CAT files is not a supported way to do it.

Hopefully we will see an improved version of setupapi.dll that will handle the API call SetupCopyOEMInf faster in XP SP3.

Link to comment
Share on other sites

I'm not really expert enough on the procedure that setupcopyoeminf.exe goes through.

...

One of the problems I have with setupcopyoeminf.exe is recovering from it. It doesn't seem so easily reversed.

The API call SetupCopyOEMInf (part of setupapi.dll) will do the following things:

- copy the INF file to %windir%\inf\oem<sequencenumber>.inf

- create %windir%\inf\oem<sequencenumber>.PNF

PNF files are very important because they contain the path to the original location of the INF file. That's the way Windows finds the driver files when it wants to install the driver.

- update the %windir%\inf\INFCACHE.1

INFCACHE.1 is an Index file that will allow Windows PnP to find a driver very quickly

PLUS if it is a signed driver:

- copy the CAT file to %windir%\system32\CatRoot\<GUID>\oem<sequencenumber>.CAT

- update the Signature Catalogs %windir%\system32\CatRoot2\.......

This is the official way how Microsoft wants OEMs to integrate their device drivers in Windows 2K/XP/2K3. Not all OEMs do it this way, though :) .

To recover from SetupCopyOEMInf.exe means to:

- delete the correct %windir%\inf\oem<sequencenumber>.inf

- delete the corresponding %windir%\inf\oem<sequencenumber>.PNF

- delete the corresponding %windir%\system32\CatRoot\<GUID>\oem<sequencenumber>.CAT (if it is a signed driver)

I'm not sure about a mechanism that will clean %windir%\inf\INFCACHE.1 and the Signature Catalogs. Maybe when Windows will install a driver it will clean up those.

Edited by schalti
Link to comment
Share on other sites

I could try rewritting SetupCopyOemInf in autoit and add the backup/recover procedures but i don't realy see option how to modify those files.. (as they are not clean text)

- update the Signature Catalogs %windir%\system32\CatRoot2\.......

- update the %windir%\inf\INFCACHE.1

maybe there are some dllcalls or so? If i remember right shalti you had some .bat files that were doing the SetupCopyOemInf procedure that was later on taken by pyron with his program.

@shalti Hope you can give us much info as you can on this. Maybe then i could implement it in my Hardware Installer program.

Link to comment
Share on other sites

I could try rewritting SetupCopyOemInf in autoit and add the backup/recover procedures but i don't realy see option how to modify those files.. (as they are not clean text)

- update the Signature Catalogs %windir%\system32\CatRoot2\.......

- update the %windir%\inf\INFCACHE.1

maybe there are some dllcalls or so? If i remember right shalti you had some .bat files that were doing the SetupCopyOemInf procedure that was later on taken by pyron with his program.

@shalti Hope you can give us much info as you can on this. Maybe then i could implement it in my Hardware Installer program.

I don't think it is possible to rewrite SetupCopyOEMInf because it is an API call of setupapi.dll. You would have to disassemble setupapi.dll and write your own optimized DLL/EXE which is almost impossible. The reason why I asked Pyron to write the tool was because he already had written the tool SetDevicePath.exe which also crawls through a subdirectory structure looking for INF files. So he could use most of his existing source code. What he does in SetupCopyOEMInf.exe is to call SetupCopyOEMInf with every INF file instead of writing the path of every INF file in a list and put the list in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DevicePath as REG_EXPAND_SZ.

This whole setupapi.dll is like a black box and all we can do is to use the documented API call SetupCopyOEMInf (MSDN on SetupCopyOEMInf).

The batch files that were online for a while are useless because they call the very same API in the end but in an even slower manner. They build an INF file and in the [DefaultInstall] Section use the INF-command CopyINF (WHDC on CopyINF) which as you can see in the documentation uses the very same API call SetupCopyOEMInf in the end. So it is even slower to use this method, and you cannot speed it up.

Bad news, I know, maybe M$ will speed up the SetupCopyOEMInf API call in XP SP3 or Vista/Longhorn Server, although I hear that there are new methods for driver integration in Vista.

Edited by schalti
Link to comment
Share on other sites

Well i already rewrote SetDevicePath in AutoIt and added support for 64bit (since the regirstry changes). But i don't know how do SetupCopyOemInf. That's why if you can pls upload those .bat files so i can learn more about the way you did it. It's easier for me to see the way it was done by you in .bat way then by pyron in C++. If i'll get the idea maybe it will be quick enough.

Link to comment
Share on other sites

Well i already rewrote SetDevicePath in AutoIt and added support for 64bit (since the regirstry changes). But i don't know how do SetupCopyOemInf. That's why if you can pls upload those .bat files so i can learn more about the way you did it. It's easier for me to see the way it was done by you in .bat way then by pyron in C++. If i'll get the idea maybe it will be quick enough.

SetDevicePath.exe is a different story :) because you have to create a Registry Entry (REG_EXPAND_SZ) there and you have to avoid double entries if there are subdirectories with more than one INF file.

SetupCopyOEMInf is an API call in the Windows DLL setupapi.dll.

Shell script / pseudo code like this:

for /F "usebackq delims=" %%i in (`dir /S /B "%~dp0*.inf"`) do call setupapi.dll->SetupCopyOEMInf(%%i)

So you run the API call SetupCopyOEMInf from setupapi.dll with each INF file you find in the subdirectory structure. That's how Pyron's SetupCopyOEMInf.exe works.

It is possible to do an API call to a windows DLL from inside an AutoIt Script (DllOpen, DllCall, DllClose), so you can integrate SetupCopyOEMInf in your tool. I can hardly wait to see if it will be faster but I doubt it.

Like this:

$dll = DllOpen("setupapi.dll")

<loop through all INF files>

$result = DllCall($dll, "int","SetupCopyOEMInf", "<INF-Filename including path>", "", 1, 8, "", 0, 0, "")

<loop next>

DllClose($dll)

Please follow the "MSDN on SetupCopyOEMInf"-Link in the other post to find out about the parameters for the API call.

BOOL WINAPI SetupCopyOEMInf(

PCTSTR SourceInfFileName, <--- important

PCTSTR OEMSourceMediaLocation, <--- NULL

DWORD OEMSourceMediaType, <--- important, set flag SPOST_PATH (1)

DWORD CopyStyle, <--- important, set at least flag SP_COPY_NOOVERWRITE (8)

PTSTR DestinationInfFileName, <--- NULL

DWORD DestinationInfFileNameSize, <--- NULL

PDWORD RequiredSize, <--- NULL

PTSTR DestinationInfFileNameComponent <--- NULL

);

See also here:

pinvoke on SetupCopyOEMInf

Hope this helps and you will get the idea :hello:

Edited by schalti
Link to comment
Share on other sites

YEah i knew there is dllcall but never realy used it and didn't knew where to start :) As for SetPathDevice in autoit for now it jsut adds every dir it finds.. even those without .ini files but i'll change it soon, shouldn't be too hard (i even have idea right now how to do it so should be done soon). Was developing something else meanwhile in my script ;) I also found that there is SetupUninstallOEMInf so maybe if Install will work i can do Uninstall also ;p So even if it will a bit slower it should be better. Calling external program from autoit makes it harder for me to control. Btw since you seems to be good with dllcalls, maybe you know a way for dllcall that will change driver signing the way it's done by hand with Properties/Hardware/DriverSigning/ignore. I tried to search a lot about it but no good way. It can be done in autoit using it's capabilities but it will be language dependant.

BOOL SetupUninstallOEMInf(

PCWSTR InfFileName,

DWORD Flags,

PVOID Reserved

);

Link to comment
Share on other sites

Maybe i am too tired but everytime i call it @error is always = 0 which means everything is great ;p It's always fine even if i change $dll_exe = DllOpen("setupapi.dll") to $dll_exe = DllOpen("setupapi11.dll") ;p

DllCall($dll_exe, "int","SetupCopyOEMInf", $full_path_to_inf, "", 1, 8, "", 0, 0, "")

I'll try to work it out tommorow but any suggestions are welcome ;p

Link to comment
Share on other sites

Maybe i am too tired but everytime i call it @error is always = 0 which means everything is great ;p It's always fine even if i change $dll_exe = DllOpen("setupapi.dll") to $dll_exe = DllOpen("setupapi11.dll") ;p

DllCall($dll_exe, "int","SetupCopyOEMInf", $full_path_to_inf, "", 1, 8, "", 0, 0, "")

I'll try to work it out tommorow but any suggestions are welcome ;p

:blushing:

Oops i just checked the syntax of DllCall again, it seems you have to pass the datatype with each parameter also.

Try the following:

DllCall($dll_exe, "int", "SetupCopyOEMInf", "str", $full_path_to_inf, "str", "", "int", 1, "int", 8, "str", "", "int", 0, "int", 0, "str", "")

If it doesn't work try to play with the datatype, the first "int" might be "none", "str" might be "wstr" if you are using Unicode.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...