1

I've implemented a SetupAPI wrapper in C# that enumerates devices based on GUIDs. I have, more or less, converted the DevCon c++ example code found on MSDN to C# (Yes I very much know that this is all veyr painfully to do in .NET, but it's fun and a challenge).

I'm able to get all the appropriate information about a certain device, but a problem occurred when I reached the "SetupScanFileQueue" method.

I cant seem to be able to make the "SetupScanFileQueue" to call my callback. The method returns true, so it seems to be working.

My end goal is to get the driver files of the specific device.

Additional information: The files appear to be added to the FileQueue correctly, I get this popup window that seems to copy the correct files.

            // create a file queue so we can look at this queue later 
            var queueHandler = SetupOpenFileQueue();
            if (queueHandler == IntPtr.Zero)
                return false;


            // modify flags to indicate we're providing our own queue 
            var deviceInstallParams = new SP_DEVINSTALL_PARAMS();
            deviceInstallParams.cbSize = Marshal.SizeOf(deviceInstallParams);
            if (!SetupDiGetDeviceInstallParams(handle, ref devInfo, ref deviceInstallParams))
            {
                error = Marshal.GetLastWin32Error();
                return false;
            }

            // we want to add the files to the file queue, not install them! 
            deviceInstallParams.FileQueue = queueHandler;
            deviceInstallParams.Flags |= DI_NOVCP;

            if (!SetupDiGetDeviceInstallParams(handle, ref devInfo, ref deviceInstallParams))
            {
                error = Marshal.GetLastWin32Error();
                return false;
            }

            // now fill queue with files that are to be installed 
            // this involves all class/co-installers 
            if (!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, handle, ref devInfo))
            {
                error = Marshal.GetLastWin32Error();
                return false;
            }

            // we now have a list of delete/rename/copy files 
            // iterate the copy queue twice - 1st time to get # of files 
            // 2nd time to get files 
            // (WinXP has API to get # of files, but we want this to work 
            // on Win2k too) 
            var scanResult = 0;
            var count = 0;
            var callback = new PSP_FILE_CALLBACK(PSP_FILEFOUND_CALLBACK);

            var t = SetupScanFileQueue(queueHandler, SPQ_SCAN_USE_CALLBACK, IntPtr.Zero,
                callback, ref count, ref scanResult);

            SetupDiDestroyDriverInfoList(handle, ref devInfo, SPDIT_CLASSDRIVER);
            if (queueHandler != IntPtr.Zero)
                SetupCloseFileQueue(queueHandler);

The definition of my Callback is as follows:

    public delegate uint PSP_FILE_CALLBACK(uint context, uint notifaction, IntPtr param1, IntPtr param2);
    public static uint PSP_FILEFOUND_CALLBACK(uint context, uint notifaction, IntPtr param1, IntPtr param2)
    {
        //This callback is never triggered
        return 0;
    }

Does anyone have any suggestions to what I'm doing wrong in the "SetupScanFileQueue" function, and why the callback is never called?

Any help is very much appreciated!

Edit:

I should also have added the DllImport for the SetupScanFileQueue function:

[DllImport("setupapi.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
    private static extern uint SetupScanFileQueue(IntPtr QueueHandle,
                                                    int Flags, 
                                                    IntPtr Window,
                                                    PSP_FILE_CALLBACK CallbackRoutine,
                                                    int CallbackContext,
                                                    out int ScanResult
        );

I've also tried it without the CallingConvention.

Community
  • 1
  • 1
Gnm
  • 129
  • 6

0 Answers0