📄 irclass.c
字号:
}
}
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 + -