/*++ Copyright (c) Microsoft Corporation. All rights reserved. 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" #pragma hdrstop #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. 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; 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