⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irclass.c

📁 This sample demonstrates the handling of DIF_ calls during device installation and the insertion of
💻 C
📖 第 1 页 / 共 4 页
字号:
    }
}

PCOINSTALLER_PRIVATE_DATA
CreatePrivateData(
                  IN     HDEVINFO                     DeviceInfoSet,
                  IN     PSP_DEVINFO_DATA             DeviceInfoData OPTIONAL
                  )
/*++

Routine Description:

    Allocs and initailizes private context data buffer

Arguments:

    DeviceInfoSet - As passed in to IrSIRClassCoInstaller
    DeviceInfoData - As passed in to IrSIRClassCoInstaller

Return Value:

    Pointer to alloced context data, or NULL if failure.  Call GetLastError()
    for extended error information.

--*/
{
    PCOINSTALLER_PRIVATE_DATA pPrivateData;
    BOOL Status = TRUE;
    UINT ErrorLine;
    TCHAR buf[100];

    pPrivateData = LocalAlloc(LPTR, sizeof(COINSTALLER_PRIVATE_DATA));

    if (!pPrivateData)
    {
#if DBG
        OutputDebugString(TEXT("IrSIRCoClassInstaller: Insufficient Memory\n"));
#endif
        Status = FALSE;
    }
    else
    {
        pPrivateData->DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
        Status = SetupDiGetSelectedDriver(DeviceInfoSet,
                                          DeviceInfoData,
                                          &pPrivateData->DriverInfoData);
        if (!Status)
        {
#if DBG
            wsprintf(buf, TEXT("IrSIRCoClassInstaller:SetupDiGetSelectedDriver failed (%d)\n"), GetLastError());
            OutputDebugString(buf);
#endif
        }
    }

    if (Status)
    {
        pPrivateData->DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
        Status = SetupDiGetDriverInfoDetail(DeviceInfoSet,
                                            DeviceInfoData,
                                            &pPrivateData->DriverInfoData,
                                            &pPrivateData->DriverInfoDetailData,
                                            sizeof(SP_DRVINFO_DETAIL_DATA),
                                            NULL);

        if (!Status)
        {
            if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
            {
                // We don't need the extended information.  Ignore.
                Status = TRUE;
            }
            else
            {
#if DBG
                wsprintf(buf, TEXT("IrSIRCoClassInstaller:SetupDiGetDriverInfoDetail failed (%d)\n"), GetLastError());
                OutputDebugString(buf);
#endif
            }
        }
    }


    if (Status)
    {
        pPrivateData->hInf = SetupOpenInfFile(pPrivateData->DriverInfoDetailData.InfFileName,
                                              NULL,
                                              INF_STYLE_WIN4,
                                              &ErrorLine);

        if (pPrivateData->hInf==INVALID_HANDLE_VALUE)
        {
            Status = FALSE;
#if DBG
            wsprintf(buf, TEXT("IrSIRCoClassInstaller:SetupOpenInfFile failed (%d) ErrorLine==%d\n"), GetLastError(), ErrorLine);
            OutputDebugString(buf);
#endif
        }
    }

    if (Status)
    {
        // Translate to the .NT name, if present.
        Status = SetupDiGetActualSectionToInstall(pPrivateData->hInf,
                                                  pPrivateData->DriverInfoDetailData.SectionName,
                                                  pPrivateData->InfSectionWithExt,
                                                  LINE_LEN,
                                                  NULL,
                                                  NULL);

        if (!Status)
        {
#if DBG
            OutputDebugString(TEXT("IrSIRCoClassInstaller:SetupDiGetActualSectionToInstall failed\n"));
#endif
        }

    }

    if (!Status)
    {
        // We experienced some failure.  Cleanup.

        DestroyPrivateData(pPrivateData);
        pPrivateData = NULL;
    }

    return pPrivateData;
}

DWORD
IrSIRClassCoInstaller(
                     IN     DI_FUNCTION                  InstallFunction,
                     IN     HDEVINFO                     DeviceInfoSet,
                     IN     PSP_DEVINFO_DATA             DeviceInfoData OPTIONAL,
                     IN OUT PCOINSTALLER_CONTEXT_DATA    pContext
                     )
/*++

Routine Description:

    This routine acts as the class coinstaller for SIR devices.  This is set up
    to be called by the INF:

[MS_Devices]
; DisplayName           Section       	DeviceID
; -----------           -------       	--------
%*PNP0510.DevDesc%    = PNP,      	*PNP0510

[PNP.NT.CoInstallers]
AddReg                = IRSIR.CoInstallers.reg

[IRSIR.CoInstallers.reg]
HKR,,CoInstallers32,0x00010000,"IRCLASS.dll,IrSIRClassCoInstaller"


Arguments:

    InstallFunction - Specifies the device installer function code indicating
        the action being performed.

    DeviceInfoSet - Supplies a handle to the device information set being
        acted upon by this install action.

    DeviceInfoData - Optionally, supplies the address of a device information
        element being acted upon by this install action.

Return Value:

    ERROR_DI_DO_DEFAULT, ERROR_DI_POSTPROCESSING_REQUIRED, or error code

--*/
{
    TCHAR buf[100];
    DWORD Result = ERROR_SUCCESS;
    LONG lResult;
    PCOINSTALLER_PRIVATE_DATA pPrivateData;
    INFCONTEXT InfContext;

#if DBG
    wsprintf(buf, TEXT("IrSIRCoClassInstaller:InstallFunction(%s) PostProcessing:%d\n"), GetDIFString(InstallFunction), pContext->PostProcessing);
    OutputDebugString(buf);
#endif


    switch (InstallFunction)
    {
        case DIF_INSTALLDEVICE:
        {
            UINT ErrorLine;

            // Private data for coinstallers is only kept across a single call,
            // pre and post processing.  The private data that we create here
            // is not any good for any other DIF_ call.
            pContext->PrivateData = CreatePrivateData(DeviceInfoSet,
                                                      DeviceInfoData);

            if (!pContext->PrivateData)
            {
                return GetLastError();
            }

            pPrivateData = pContext->PrivateData;

            {
                // NOTE on the use of UPPERFILTERS and LOWERFILTERS
                // A filter driver is a driver that is loaded as a shim above
                // or below another driver, in this case SERIAL below IRSIR.
                // It does special processing on IRPs and can give added
                // functionality or is a means to avoid duplicate functionality
                // in multiple drivers.  UPPERFILTERS and LOWERFILTERS values
                // are used by the PnP system to identify and load filter
                // drivers.  These values could be set via the INF in a .HW
                // section, but setting them via the coinstaller may give you
                // more control, i.e. you could remove one of several filter
                // drivers from a list.
                //
                // If your driver isn't a filter driver, or doesn't use filter
                // drivers, you won't need to clear these values as is done
                // here.


                // Always clear UpperFilters.  If this is an upgrade from
                // a post-1671, the IrDA device could have been installed as
                // a serial port, with a serenum upper filter.  This will
                // blow up NDIS, so clear it.
                //
                // This is atypical behavior for a class coinstaller.  Normally
                // the upperfilter/lowerfilter values do not need to be touched.

                // Note that it is possible to do this from the INF.  This
                // is here more for demo purpose.

                SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
                                                 DeviceInfoData,
                                                 SPDRP_UPPERFILTERS,
                                                 NULL,
                                                 0);
            }

            if (SetupFindFirstLine(pPrivateData->hInf,
                                   pPrivateData->InfSectionWithExt,
                                   TEXT("LowerFilters"),
                                   &InfContext))
            {
                TCHAR LowerFilters[LINE_LEN];
                DWORD BytesNeeded;
                if (!SetupGetMultiSzField(&InfContext, 1, LowerFilters, LINE_LEN, &BytesNeeded))
                {
                    // Lowerfilters value was not found in the inf.
                    // This means we do not want a lowerfilters value in
                    // the registry.  (Unique to IRSIR.SYS and NETIRSIR.INF)

                    // Setting lowerfilters here for demo purpose only.
                    // Normally done from INF, if necessary at all.
                    if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
                                                          DeviceInfoData,
                                                          SPDRP_LOWERFILTERS,
                                                          NULL,
                                                          0)
                       )
                    {
#if DBG
                        OutputDebugString(TEXT("IrSIRCoClassInstaller: Failed to set lowerfilter\n"));
#endif
                    }

                }
                else
                {
                    // Setting lowerfilters here for demo purpose only.
                    // Normally done from INF, if necessary at all.
                    if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
                                                          DeviceInfoData,
                                                          SPDRP_LOWERFILTERS,
                                                          (LPBYTE)LowerFilters,
                                                          ((BytesNeeded<LINE_LEN) ?
                                                           BytesNeeded : LINE_LEN)*sizeof(TCHAR))
                       )
                    {
#if DBG
                        OutputDebugString(TEXT("IrSIRCoClassInstaller: Failed to set lowerfilter\n"));
#endif
                    }
                }
            }
            else
            {
                // No lowerfilters value present.  Clear it.
                // Setting lowerfilters here for demo purpose only.
                // Normally done from INF, if necessary at all.
                if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
                                                      DeviceInfoData,
                                                      SPDRP_LOWERFILTERS,
                                                      NULL,
                                                      0)
                   )
                {
#if DBG
                    OutputDebugString(TEXT("IrSIRCoClassInstaller: Failed to set lowerfilter\n"));
#endif
                }
            }

            DestroyPrivateData(pContext->PrivateData);
            pContext->PrivateData = NULL;
            break;
        }
        case DIF_NEWDEVICEWIZARD_FINISHINSTALL:
        {
            pContext->PrivateData = CreatePrivateData(DeviceInfoSet,
                                                      DeviceInfoData);

            if (!pContext->PrivateData)
            {
                return GetLastError();
            }

            pPrivateData = pContext->PrivateData;

            if (!SetupFindFirstLine(pPrivateData->hInf,
                                    pPrivateData->InfSectionWithExt,
                                    TEXT("PromptForPort"),
                                    &InfContext))
            {
#if DBG
                OutputDebugString(TEXT("IrSIRCoClassInstaller:failed to find PromptForPort in .INF\n"));
#endif
            }
            else
            {
                if (!SetupGetIntField(&InfContext, 1, &pPrivateData->PromptForPort))
                {
#if DBG
                    OutputDebugString(TEXT("IrSIRCoClassInstaller:failed to read PromptForPort in .INF\n"));
#endif

                    // Default to true
                    pPrivateData->PromptForPort = TRUE;
                }

                // If we have a COM port we need to query the user, UNLESS
                // this is an upgrade.
                if (pPrivateData->PromptForPort && !IsPortValueSet(DeviceInfoSet, DeviceInfoData))
                {
                    PortSelectionDlg(DeviceInfoSet, DeviceInfoData);
                }
            }
            if (!pPrivateData->PromptForPort)
            {
                TCHAR *pszLocation;
                if (MyLoadString(ghDllInst, IDS_INTERNAL_PORT, &pszLocation))
                {
                    SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
                                                     DeviceInfoData,
                                                     SPDRP_LOCATION_INFORMATION,
                                                     (LPBYTE)pszLocation,
                                                     (1+lstrlen(pszLocation))*sizeof(TCHAR));
                    LocalFree(pszLocation);
                }

            }

            DestroyPrivateData(pContext->PrivateData);
            pContext->PrivateData = NULL;
            break;
        }
        default:
        {
            break;
        }
    }
#if DBG
    wsprintf(buf, TEXT("IrSIRCoClassInstaller:returning:0x%08x\n"), Result);
    OutputDebugString(buf);
#endif
    return Result;
}


BOOL APIENTRY IrSIRPortPropPageProvider(LPVOID               pinfo,
                                        LPFNADDPROPSHEETPAGE pfnAdd,
                                        LPARAM               lParam
                                       )
/*++

Routine Description:

    Entry-point for adding additional device manager property
    sheet pages.  This entry-point gets called only when the Device
    Manager asks for additional property pages.  The INF associated with
    this causes it to be called by specifying it in an AddReg section:

[IRSIR.reg]
HKR,  ,               EnumPropPages32,	,	"IRCLASS.dll,IrSIRPortPropPageProvider"


Arguments:

    pinfo  - points to PROPSHEETPAGE_REQUEST, see setupapi.h
    pfnAdd - function ptr to call to add sheet.
    lParam - add sheet functions private data handle.

Return Value:

    BOOL: FALSE if pages could not be added, TRUE on success

--*/
{
    PSP_PROPSHEETPAGE_REQUEST pprPropPageRequest;
    HKEY hKey = 0;
    PROPSHEETPAGE    PropSheetPage;
    HPROPSHEETPAGE   hspPropSheetPage;
    PPROPPAGEPARAMS  pPropParams = NULL;

    pPropParams = LocalAlloc(LMEM_FIXED, sizeof(PROPPAGEPARAMS));
    if (!pPropParams)
    {
        return FALSE;
    }

    pprPropPageRequest = (PSP_PROPSHEETPAGE_REQUEST) pinfo;

    pPropParams->Signature = PPParamsSignature;
    pPropParams->DeviceInfoSet = pprPropPageRequest->DeviceInfoSet;
    pPropParams->DeviceInfoData = pprPropPageRequest->DeviceInfoData;
    pPropParams->FirstTimeInstall = FALSE;

    if (pprPropPageRequest->PageRequested == SPPSR_ENUM_ADV_DEVICE_PROPERTIES)
    {
        //
        // Setup the advanced properties window information
        //
        BOOLEAN bResult;
        DWORD   RequiredSize = 0;
        DWORD   dwTotalSize = 0;

        memset(&PropSheetPage, 0, sizeof(PropSheetPage));
        //
        // Add the Port Settings property page
        //
        PropSheetPage.dwSize      = sizeof(PROPSHEETPAGE);
        PropSheetPage.dwFlags     = PSP_USECALLBACK; // | PSP_HASHELP;
        PropSheetPage.hInstance   = ghDllInst;
        PropSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_PP_IRDA_SETTINGS);

        //
        // following points to the dlg window proc
        //
        PropSheetPage.pfnDlgProc = PortDlgProc;
        PropSheetPage.lParam     = (LPARAM)pPropParams;

        //
        // following points to some control callback of the dlg window proc
        //
        PropSheetPage.pfnCallback = NULL;

        //
        // allocate our "Ports Setting" sheet
        //
        hspPropSheetPage = CreatePropertySheetPage(&PropSheetPage);
        if (!hspPropSheetPage)
        {
            return FALSE;
        }

        //
        // add the thing in.
        //
        if (!pfnAdd(hspPropSheetPage, lParam))
        {
            DestroyPropertySheetPage(hspPropSheetPage);
            return FALSE;
        }
    }
    else
    {
        LocalFree(pPropParams);
    }

    return TRUE;

} /* IrSIRPortPropPageProvider */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -