mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 16:51:18 +00:00

Not all files are included, but these are necessary to compile cdrom driver. So far it can only be statically linked with drivers, a proper implementation requires wdfldr helper driver
403 lines
10 KiB
C++
403 lines
10 KiB
C++
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
FxDeviceInterfaceAPI.cpp
|
|
|
|
Abstract:
|
|
|
|
This module implements the device interface object external APIs
|
|
|
|
Author:
|
|
|
|
|
|
|
|
|
|
Environment:
|
|
|
|
kernel and user mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "fxsupportpch.hpp"
|
|
|
|
extern "C" {
|
|
// #include "FxDeviceInterfaceAPI.tmh"
|
|
}
|
|
|
|
//
|
|
// extern "C" the entire file
|
|
//
|
|
extern "C" {
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
STDCALL
|
|
WDFEXPORT(WdfDeviceCreateDeviceInterface)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFDEVICE Device,
|
|
__in
|
|
CONST GUID *InterfaceClassGUID,
|
|
__in_opt
|
|
PCUNICODE_STRING ReferenceString
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates a device interface associated with the passed in device object
|
|
|
|
Arguments:
|
|
Device - Handle which represents the device exposing the interface
|
|
|
|
InterfaceGUID - GUID describing the interface being exposed
|
|
|
|
ReferenceString - OPTIONAL string which allows the driver writer to
|
|
distinguish between different exposed interfaces
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS or appropriate NTSTATUS code
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
SINGLE_LIST_ENTRY **ppPrev, *pCur;
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxDeviceInterface *pDeviceInterface;
|
|
FxDevice *pDevice;
|
|
FxPkgPnp* pPkgPnp;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
Device,
|
|
FX_TYPE_DEVICE,
|
|
(PVOID*) &pDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, InterfaceClassGUID);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
if (ReferenceString != NULL) {
|
|
status = FxValidateUnicodeString(pFxDriverGlobals, ReferenceString);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
}
|
|
|
|
if (pDevice->IsLegacy()) {
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
|
|
"WDFDEVICE %p is not a PNP device, device interface creation not "
|
|
"allowed %!STATUS!", Device, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
pDeviceInterface = new(pFxDriverGlobals, PagedPool) FxDeviceInterface();
|
|
|
|
if (pDeviceInterface == NULL) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
|
|
"WDFDEVICE %p DeviceInterface object creation failed, %!STATUS!",
|
|
Device, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
status = pDeviceInterface->Initialize(pFxDriverGlobals,
|
|
InterfaceClassGUID,
|
|
ReferenceString);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
|
|
"WDFDEVICE %p, DeviceInterface object initialization failed, %!STATUS!",
|
|
Device, status );
|
|
|
|
goto Done;
|
|
}
|
|
|
|
pPkgPnp = pDevice->m_PkgPnp;
|
|
|
|
pPkgPnp->m_DeviceInterfaceLock.AcquireLock(pFxDriverGlobals);
|
|
|
|
status = pDeviceInterface->Register(pDevice);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
//
|
|
// Insert into the end of the list
|
|
//
|
|
ppPrev = &pPkgPnp->m_DeviceInterfaceHead.Next;
|
|
pCur = pPkgPnp->m_DeviceInterfaceHead.Next;
|
|
while (pCur != NULL) {
|
|
ppPrev = &pCur->Next;
|
|
pCur = pCur->Next;
|
|
}
|
|
|
|
*ppPrev = &pDeviceInterface->m_Entry;
|
|
}
|
|
|
|
pPkgPnp->m_DeviceInterfaceLock.ReleaseLock(pFxDriverGlobals);
|
|
|
|
Done:
|
|
if (!NT_SUCCESS(status)) {
|
|
delete pDeviceInterface;
|
|
pDeviceInterface = NULL;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
VOID
|
|
STDCALL
|
|
WDFEXPORT(WdfDeviceSetDeviceInterfaceState)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFDEVICE Device,
|
|
__in
|
|
CONST GUID *InterfaceClassGUID,
|
|
__in_opt
|
|
PCUNICODE_STRING RefString,
|
|
__in
|
|
BOOLEAN State
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PSINGLE_LIST_ENTRY ple;
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
NTSTATUS status;
|
|
FxDevice* pDevice;
|
|
FxPkgPnp* pPkgPnp;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
Device,
|
|
FX_TYPE_DEVICE,
|
|
(PVOID*) &pDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, InterfaceClassGUID);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
FxVerifierDbgBreakPoint(pFxDriverGlobals);
|
|
return;
|
|
}
|
|
|
|
if (RefString != NULL) {
|
|
status = FxValidateUnicodeString(pFxDriverGlobals, RefString);
|
|
if (!NT_SUCCESS(status)) {
|
|
FxVerifierDbgBreakPoint(pFxDriverGlobals);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (pDevice->IsLegacy()) {
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
|
|
"WDFDEVICE %p is not a PNP device, device interfaces not allowed",
|
|
Device);
|
|
FxVerifierDbgBreakPoint(pFxDriverGlobals);
|
|
return;
|
|
}
|
|
|
|
pPkgPnp = pDevice->m_PkgPnp;
|
|
|
|
pPkgPnp->m_DeviceInterfaceLock.AcquireLock(pFxDriverGlobals);
|
|
|
|
//
|
|
// Iterate over the interfaces and see if we have a match
|
|
//
|
|
for (ple = pPkgPnp->m_DeviceInterfaceHead.Next; ple != NULL; ple = ple->Next) {
|
|
FxDeviceInterface *pDI;
|
|
|
|
pDI = FxDeviceInterface::_FromEntry(ple);
|
|
|
|
if (FxIsEqualGuid(&pDI->m_InterfaceClassGUID, InterfaceClassGUID)) {
|
|
if (RefString != NULL) {
|
|
if ((RefString->Length == pDI->m_ReferenceString.Length)
|
|
&&
|
|
(RtlCompareMemory(RefString->Buffer,
|
|
pDI->m_ReferenceString.Buffer,
|
|
RefString->Length) == RefString->Length)) {
|
|
//
|
|
// They match, carry on
|
|
//
|
|
DO_NOTHING();
|
|
}
|
|
else {
|
|
//
|
|
// The ref strings do not match, continue on in the search
|
|
// of the collection.
|
|
//
|
|
continue;
|
|
}
|
|
}
|
|
else if (pDI->m_ReferenceString.Length > 0) {
|
|
//
|
|
// Caller didn't specify a ref string but this interface has
|
|
// one, continue on in the search through the collection.
|
|
//
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Set the state and break out of the loop because we found our
|
|
// interface.
|
|
//
|
|
pDI->SetState(State);
|
|
break;
|
|
}
|
|
}
|
|
|
|
pPkgPnp->m_DeviceInterfaceLock.ReleaseLock(pFxDriverGlobals);
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
STDCALL
|
|
WDFEXPORT(WdfDeviceRetrieveDeviceInterfaceString)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFDEVICE Device,
|
|
__in
|
|
CONST GUID* InterfaceClassGUID,
|
|
__in_opt
|
|
PCUNICODE_STRING RefString,
|
|
__in
|
|
WDFSTRING String
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Returns the symbolic link value of the registered device interface.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PSINGLE_LIST_ENTRY ple;
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxDevice* pDevice;
|
|
FxPkgPnp* pPkgPnp;
|
|
FxString* pString;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
Device,
|
|
FX_TYPE_DEVICE,
|
|
(PVOID*) &pDevice,
|
|
&pFxDriverGlobals );
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, InterfaceClassGUID);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
if (RefString != NULL) {
|
|
status = FxValidateUnicodeString(pFxDriverGlobals, RefString);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
}
|
|
|
|
if (pDevice->IsLegacy()) {
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGERROR,
|
|
"WDFDEVICE %p is not a PNP device, device interface creation not "
|
|
"allowed %!STATUS!", Device, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
FxObjectHandleGetPtr(pFxDriverGlobals,
|
|
String,
|
|
FX_TYPE_STRING,
|
|
(PVOID*) &pString);
|
|
|
|
pPkgPnp = pDevice->m_PkgPnp;
|
|
|
|
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
|
|
|
pPkgPnp->m_DeviceInterfaceLock.AcquireLock(pFxDriverGlobals);
|
|
|
|
//
|
|
// Iterate over the interfaces and see if we have a match
|
|
//
|
|
for (ple = pPkgPnp->m_DeviceInterfaceHead.Next;
|
|
ple != NULL;
|
|
ple = ple->Next) {
|
|
FxDeviceInterface *pDI;
|
|
|
|
pDI = FxDeviceInterface::_FromEntry(ple);
|
|
|
|
if (FxIsEqualGuid(&pDI->m_InterfaceClassGUID, InterfaceClassGUID)) {
|
|
if (RefString != NULL) {
|
|
if ((RefString->Length == pDI->m_ReferenceString.Length)
|
|
&&
|
|
(RtlCompareMemory(RefString->Buffer,
|
|
pDI->m_ReferenceString.Buffer,
|
|
RefString->Length) == RefString->Length)) {
|
|
//
|
|
// They match, carry on
|
|
//
|
|
DO_NOTHING();
|
|
}
|
|
else {
|
|
//
|
|
// The ref strings do not match, continue on in the search
|
|
// of the collection.
|
|
//
|
|
continue;
|
|
}
|
|
}
|
|
else if (pDI->m_ReferenceString.Length > 0) {
|
|
//
|
|
// Caller didn't specify a ref string but this interface has
|
|
// one, continue on in the search through the collection.
|
|
//
|
|
continue;
|
|
}
|
|
|
|
status = pDI->GetSymbolicLinkName(pString);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
pPkgPnp->m_DeviceInterfaceLock.ReleaseLock(pFxDriverGlobals);
|
|
|
|
return status;
|
|
}
|
|
|
|
} // extern "C"
|