220 lines
5.4 KiB
C
220 lines
5.4 KiB
C
/*++
|
||
|
||
Copyright (c) 1995-2001 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
rconflist.c
|
||
|
||
Abstract:
|
||
|
||
This module contains the server-side conflict list reporting APIs.
|
||
|
||
PNP_QueryResConfList
|
||
|
||
Author:
|
||
|
||
Paula Tomlinson (paulat) 9-27-1995
|
||
|
||
Environment:
|
||
|
||
User-mode only.
|
||
|
||
Revision History:
|
||
|
||
27-Sept-1995 paulat
|
||
|
||
Creation and initial implementation.
|
||
|
||
--*/
|
||
|
||
|
||
//
|
||
// includes
|
||
//
|
||
#include "precomp.h"
|
||
#include "umpnpi.h"
|
||
|
||
|
||
//
|
||
// private prototypes
|
||
//
|
||
CONFIGRET
|
||
ResDesToNtResource(
|
||
IN PCVOID ResourceData,
|
||
IN RESOURCEID ResourceID,
|
||
IN ULONG ResourceLen,
|
||
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDes,
|
||
IN ULONG ulTag,
|
||
IN ULONG ulFlags
|
||
);
|
||
|
||
ULONG
|
||
GetResDesSize(
|
||
IN ULONG ResourceID,
|
||
IN ULONG ulFlags
|
||
);
|
||
|
||
|
||
|
||
CONFIGRET
|
||
PNP_QueryResConfList(
|
||
IN handle_t hBinding,
|
||
IN LPWSTR pDeviceID,
|
||
IN RESOURCEID ResourceID,
|
||
IN LPBYTE ResourceData,
|
||
IN ULONG ResourceLen,
|
||
OUT LPBYTE clBuffer,
|
||
IN ULONG clBufferLen,
|
||
IN ULONG ulFlags
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This the server-side of an RPC remote call. This routine retrieves
|
||
conflict information for a specified resource.
|
||
|
||
Arguments:
|
||
|
||
hBinding RPC binding handle, not used.
|
||
|
||
pDeviceID Null-terminated device instance id string.
|
||
|
||
ResourceID Type of resource, ResType_xxxx
|
||
|
||
ResourceData Resource specific data
|
||
|
||
ResourceLen length of ResourceData
|
||
|
||
clBuffer Buffer filled with conflict list
|
||
|
||
clBufferLen Size of clBuffer
|
||
|
||
ulFlags Specifies the width of certain variable-size resource
|
||
descriptor structure fields, where applicable.
|
||
|
||
Currently, the following flags are defined:
|
||
|
||
CM_RESDES_WIDTH_32 or
|
||
CM_RESDES_WIDTH_64
|
||
|
||
If no flags are specified, the width of the variable-sized
|
||
resource data supplied is assumed to be that native to the
|
||
platform of the caller.
|
||
|
||
Return Value:
|
||
|
||
If the specified device instance is valid, it returns CR_SUCCESS,
|
||
otherwise it returns CR_ error code.
|
||
|
||
--*/
|
||
|
||
{
|
||
CONFIGRET Status = CR_SUCCESS;
|
||
NTSTATUS NtStatus = STATUS_SUCCESS;
|
||
PLUGPLAY_CONTROL_CONFLICT_DATA ControlData;
|
||
PPLUGPLAY_CONTROL_CONFLICT_LIST pConflicts;
|
||
CM_RESOURCE_LIST NtResourceList;
|
||
ULONG Index;
|
||
|
||
UNREFERENCED_PARAMETER(hBinding);
|
||
|
||
try {
|
||
//
|
||
// validate parameters
|
||
//
|
||
if (INVALID_FLAGS(ulFlags, CM_RESDES_WIDTH_BITS)) {
|
||
Status = CR_INVALID_FLAG;
|
||
goto Clean0;
|
||
}
|
||
|
||
//
|
||
// validate res des size
|
||
//
|
||
if (ResourceLen < GetResDesSize(ResourceID, ulFlags)) {
|
||
Status = CR_INVALID_DATA;
|
||
goto Clean0;
|
||
}
|
||
|
||
if (!IsLegalDeviceId(pDeviceID)) {
|
||
Status = CR_INVALID_DEVNODE;
|
||
goto Clean0;
|
||
}
|
||
|
||
//
|
||
// make sure original caller didn't specify root devnode
|
||
//
|
||
if (IsRootDeviceID(pDeviceID)) {
|
||
Status = CR_INVALID_LOG_CONF;
|
||
goto Clean0;
|
||
}
|
||
|
||
//
|
||
// look at buffer we need to fill in
|
||
// validate parameters passed in buffer
|
||
// buffer should always be big enough to hold header
|
||
//
|
||
if(clBufferLen < sizeof(PPLUGPLAY_CONTROL_CONFLICT_LIST)) {
|
||
Status = CR_INVALID_STRUCTURE_SIZE;
|
||
goto Clean0;
|
||
}
|
||
|
||
pConflicts = (PPLUGPLAY_CONTROL_CONFLICT_LIST)clBuffer;
|
||
|
||
//
|
||
// Convert the user-mode version of the resource list to an
|
||
// NT CM_RESOURCE_LIST structure.
|
||
//
|
||
// we'll sort out InterfaceType and BusNumber in kernel
|
||
//
|
||
NtResourceList.Count = 1;
|
||
NtResourceList.List[0].InterfaceType = InterfaceTypeUndefined;
|
||
NtResourceList.List[0].BusNumber = 0;
|
||
NtResourceList.List[0].PartialResourceList.Version = NT_RESLIST_VERSION;
|
||
NtResourceList.List[0].PartialResourceList.Revision = NT_RESLIST_REVISION;
|
||
NtResourceList.List[0].PartialResourceList.Count = 1;
|
||
|
||
Status = ResDesToNtResource(ResourceData, ResourceID, ResourceLen,
|
||
&NtResourceList.List[0].PartialResourceList.PartialDescriptors[0], 0, ulFlags);
|
||
if (Status != CR_SUCCESS) {
|
||
goto Clean0;
|
||
}
|
||
|
||
//
|
||
// now fill in ControlData
|
||
//
|
||
RtlInitUnicodeString(&ControlData.DeviceInstance, pDeviceID);
|
||
ControlData.ResourceList = &NtResourceList;
|
||
ControlData.ResourceListSize = sizeof(NtResourceList);
|
||
ControlData.ConflictBuffer = pConflicts;
|
||
ControlData.ConflictBufferSize = clBufferLen;
|
||
ControlData.Flags = ulFlags;
|
||
ControlData.Status = STATUS_SUCCESS;
|
||
|
||
NtStatus = NtPlugPlayControl(PlugPlayControlQueryConflictList,
|
||
&ControlData,
|
||
sizeof(ControlData));
|
||
|
||
if (NtStatus == STATUS_SUCCESS) {
|
||
Status = CR_SUCCESS;
|
||
} else {
|
||
Status = MapNtStatusToCmError(NtStatus);
|
||
}
|
||
|
||
Clean0:
|
||
NOTHING;
|
||
|
||
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||
//
|
||
// unspecified failure
|
||
//
|
||
Status = CR_FAILURE;
|
||
}
|
||
|
||
return Status;
|
||
|
||
} // PNP_QueryResConfList
|
||
|