#include "pch.h" #include "cmdata.h" BOOL SoftPCI_GetNextResourceDescriptorData( IN OUT PRES_DES ResourceDescriptor, OUT PCM_RES_DATA CmResData ); VOID SoftPCI_FreeResourceDescriptorData( IN PCM_RES_DATA CmResData ); VOID SoftPCI_DumpCmResData( IN PCM_RES_DATA CmResData, OUT PWCHAR Buffer ); VOID SoftPCI_EnableDisableDeviceNode( IN DEVNODE DeviceNode, IN BOOL EnableDevice ) { if (EnableDevice) { CM_Enable_DevNode(DeviceNode, 0); }else{ if ((MessageBox(g_SoftPCIMainWnd, L"This option will disable and unloaded the driver for this device. HW remains physically present.", L"WARNING", MB_OKCANCEL)) == IDOK){ CM_Disable_DevNode(DeviceNode, 0); } } } BOOL SoftPCI_GetDeviceNodeProblem( IN DEVNODE DeviceNode, OUT PULONG DeviceProblem ) { CONFIGRET cr; ULONG dnStatus; cr = CM_Get_DevNode_Status(&dnStatus, DeviceProblem, DeviceNode, 0); if (cr == CR_SUCCESS && ((dnStatus & DN_HAS_PROBLEM) != 0)) { // // We have a problem, if it that we are disabled then return TRUE // return TRUE; } return FALSE; } BOOL SoftPCI_GetBusDevFuncFromDevnode( IN DEVNODE Dn, OUT PULONG Bus, OUT PSOFTPCI_SLOT Slot ) /*-- Routine Description: This function takes a devnode and works out the devices Bus, Device, and Function numbers. Arguments: Dn - DeviceNode to get location info for Bus - retrieved bus number Dev - retrieved device number Func - retrieved function number Return Value: TRUE if successful, FALSE otherwise --*/ { WCHAR locationinfo[MAX_PATH]; ULONG length = MAX_PATH; ULONG device = 0, function = 0; // // Get the Location info of the device via the registry api // if ((CM_Get_DevNode_Registry_Property(Dn, CM_DRP_LOCATION_INFORMATION, NULL, &locationinfo, &length, 0 ))==CR_SUCCESS){ // // Now scan the returned information for the numbers we are after. // // Note: This is dependant on the format of the loaction information // taken from the registry and if it should ever change this will break. // Should probably look into better solution. // if (swscanf(locationinfo, L"PCI bus %d, device %d, function %d", Bus, &device, &function)) { Slot->Device = (UCHAR)device; Slot->Function = (UCHAR)function; SoftPCI_Debug(SoftPciDevice, L"Bus 0x%02x, Device 0x%02x, Function 0x%02x\n", *Bus, device, function); return TRUE; } } SoftPCI_Debug(SoftPciDevice, L"Failed to get Bus Dev Func for devnode 0x%x\n", Dn); return FALSE; } BOOL SoftPCI_GetFriendlyNameFromDevNode( IN DEVNODE Dn, IN PWCHAR Buffer ) { ULONG length = MAX_PATH; // // Get the FriendlyName of the device // if ((CM_Get_DevNode_Registry_Property(Dn, CM_DRP_DEVICEDESC, NULL, Buffer, &length, 0 )) != CR_SUCCESS){ SoftPCI_Debug(SoftPciDevice, L"Failed to get friendly name for devnode 0x%x\n", Dn); return FALSE; } return TRUE; } BOOL SoftPCI_GetPciRootBusNumber( IN DEVNODE Dn, OUT PULONG Bus ) { DEVNODE child = 0; ULONG length = sizeof(ULONG); *Bus = 0xFFFFFFFF; if ((CM_Get_Child(&child, Dn, 0)==CR_SUCCESS)){ if ((CM_Get_DevNode_Registry_Property(child, CM_DRP_BUSNUMBER, NULL, Bus, &length, 0 ))!=CR_SUCCESS){ SoftPCI_Debug(SoftPciDevice, L"Failed to get bus number from child 0x%x for devnode 0x%x\n", child, Dn); return FALSE; } } return TRUE; } BOOL SoftPCI_GetNextResourceDescriptorData( IN OUT PRES_DES ResourceDescriptor, OUT PCM_RES_DATA CmResData ) { RES_DES resDes; ULONG resSize = 0; PULONG resBuf = NULL; RESOURCEID resID; CONFIGRET cr = CR_SUCCESS; if (CmResData->ResourceDescriptor) { free(CmResData->ResourceDescriptor); CmResData->ResourceDescriptor = NULL; } // // Stash away the current RES_DES handle so we dont lose it and leak mem // resDes = *ResourceDescriptor; if ((CM_Get_Next_Res_Des(ResourceDescriptor, *ResourceDescriptor, ResType_All, &resID, 0 )==CR_SUCCESS)){ if ((CM_Get_Res_Des_Data_Size(&resSize, *ResourceDescriptor, 0)) == CR_SUCCESS){ resBuf = (PULONG) calloc(1, resSize); if (resBuf == NULL) { return FALSE; } CmResData->ResourceId = resID; CmResData->DescriptorSize = resSize; CmResData->ResourceDescriptor = resBuf; SoftPCI_Debug(SoftPciCmData, L"GetNextResourceDescriptorData - ResourceId = 0x%x\n", resID); SoftPCI_Debug(SoftPciCmData, L"GetNextResourceDescriptorData - DescriptorSize = 0x%x\n", resSize); if ((cr = CM_Get_Res_Des_Data(*ResourceDescriptor, resBuf, resSize, 0)) == CR_SUCCESS){ SoftPCI_Debug(SoftPciCmData, L"GetNextResourceDescriptorData - ResourceDescriptor = 0x%x\n", resBuf); // // Free out last handle // CM_Free_Res_Des_Handle(resDes); return TRUE; }else{ SoftPCI_Debug(SoftPciCmData, L"GetNextResourceDescriptorData - failed to get ResData. (%s)\n", SoftPCI_CmResultTable[cr]); } } } if (CmResData->ResourceDescriptor) { free(CmResData->ResourceDescriptor); CmResData->ResourceDescriptor = NULL; } return FALSE; } VOID SoftPCI_FreeResourceDescriptorData( IN PCM_RES_DATA CmResData ) { if (CmResData->ResourceDescriptor) { free(CmResData->ResourceDescriptor); CmResData->ResourceDescriptor = NULL; } } BOOL SoftPCI_GetResources( PPCI_DN Pdn, PWCHAR Buffer, ULONG ConfigType ) { BOOL result = FALSE; LOG_CONF logConf; RES_DES resDes; CM_RES_DATA cmResData; RtlZeroMemory(&cmResData, sizeof(CM_RES_DATA)); // // First get the logconf. // Next get the first resource descrpitor. // if ((CM_Get_First_Log_Conf(&logConf, Pdn->DevNode, ConfigType)) == CR_SUCCESS){ resDes = (RES_DES)logConf; while (SoftPCI_GetNextResourceDescriptorData((PRES_DES)&resDes, &cmResData)) { SoftPCI_Debug(SoftPciCmData, L"GetCurrentResources - Success!\n"); SoftPCI_DumpCmResData(&cmResData, Buffer); SoftPCI_FreeResourceDescriptorData(&cmResData); result = TRUE; } // // Free out remaining RES_DES handle and then release the logconf handle // CM_Free_Res_Des_Handle(resDes); CM_Free_Log_Conf_Handle(logConf); } return result; } VOID SoftPCI_DumpCmResData( IN PCM_RES_DATA CmResData, OUT PWCHAR Buffer ) { PMEM_DES memDes; PIO_DES ioDes; PDMA_DES dmaDes; PIRQ_DES irqDes; PBUSNUMBER_DES busDes; //PMEM_RANGE memRange; //PIO_RANGE ioRange; //PDMA_RANGE dmaRange; //PIRQ_RANGE irqRange; INT i = 0; UCHAR busNum; switch (CmResData->ResourceId){ case ResType_Mem: memDes = (PMEM_DES) CmResData->ResourceDescriptor; if (CmResData->DescriptorSize < sizeof(MEM_DES)) { SoftPCI_Debug(SoftPciCmData, L"MEM No information available\n"); break; } wsprintf(Buffer + wcslen(Buffer), L" MEM \tStart: 0x%08X\tEnd: 0x%08X\r\n", //L"\tMEM \t0x%08x - 0x%08x\r\n", (DWORD)memDes->MD_Alloc_Base, (DWORD)memDes->MD_Alloc_End ); SoftPCI_Debug(SoftPciCmData, L"MEM Count:%08x Type: %08x Bas:%08x End:%08x Flags:%04x\n", memDes->MD_Count, memDes->MD_Type, (DWORD)memDes->MD_Alloc_Base, (DWORD)memDes->MD_Alloc_End, memDes->MD_Flags ); #if 0 memRange = (PMEM_RANGE)((LPBYTE)memDes + sizeof(MEM_DES)); for (i = 0; i < (INT)(memDes->MD_Count); i++){ SoftPCI_Debug(SoftPciCmData, L" Align:%08lx Bytes:%08lx Min:%08lx Max:%08lx Flags:%04x\n", (DWORD)memRange->MR_Align, memRange->MR_nBytes, (DWORD)memRange->MR_Min, (DWORD)memRange->MR_Max, memRange->MR_Flags ); memRange++; } #endif break; case ResType_IO: ioDes = (PIO_DES) CmResData->ResourceDescriptor; if (CmResData->DescriptorSize < sizeof(IO_DES)) { SoftPCI_Debug(SoftPciCmData, L"IO No information available\n"); break; } wsprintf(Buffer + wcslen(Buffer), L" IO \tStart: 0x%08X\tEnd: 0x%08X\r\n", //L"\tIO \t0x%08x - 0x%08x\r\n", (DWORD)ioDes->IOD_Alloc_Base, (DWORD)ioDes->IOD_Alloc_End ); SoftPCI_Debug(SoftPciCmData, L"IO Count:%08x Type: %08x Bas:%08x End:%08x Flags:%04x %s\n", ioDes->IOD_Count, ioDes->IOD_Type, (DWORD)ioDes->IOD_Alloc_Base, (DWORD)ioDes->IOD_Alloc_End, ioDes->IOD_DesFlags, ((ioDes->IOD_DesFlags & fIOD_PortType)==fIOD_Memory) ? L"(memory)" : L"" ); break; case ResType_IRQ: irqDes = (PIRQ_DES) CmResData->ResourceDescriptor; if (CmResData->DescriptorSize < sizeof(IRQ_DES)) { SoftPCI_Debug(SoftPciCmData, L"IRQ No information available\n"); break; } wsprintf(Buffer + wcslen(Buffer), L" IRQ \tStart: 0x%08X\tEnd: 0x%08X\r\n", //L"\tIRQ \t0x%08\r\n", irqDes->IRQD_Alloc_Num, irqDes->IRQD_Alloc_Num ); SoftPCI_Debug(SoftPciCmData, L"IRQ Count:%04X Type:%04X Channel:%04X Affinity:%0Xx Flags:%04x\n", irqDes->IRQD_Count, irqDes->IRQD_Type, irqDes->IRQD_Alloc_Num, irqDes->IRQD_Affinity, irqDes->IRQD_Flags); break; case ResType_BusNumber: busDes = (PBUSNUMBER_DES) CmResData->ResourceDescriptor; if (CmResData->DescriptorSize < sizeof(BUSNUMBER_DES)) { SoftPCI_Debug(SoftPciCmData, L"BUS No information available\n"); break; } wsprintf(Buffer + wcslen(Buffer), L" BUS \tStart: 0x%08X\tEnd: 0x%08X\r\n", busDes->BUSD_Alloc_Base, busDes->BUSD_Alloc_End ); break; case ResType_DMA: dmaDes = (PDMA_DES) CmResData->ResourceDescriptor; if (CmResData->DescriptorSize < sizeof(DMA_DES)) { SoftPCI_Debug(SoftPciCmData, L"DMA No information available\n"); break; } wsprintf(Buffer + wcslen(Buffer), L" DMA \tStart: 0x%08X\t End: 0x%08X\r\n", dmaDes->DD_Alloc_Chan, dmaDes->DD_Alloc_Chan ); SoftPCI_Debug(SoftPciCmData, L"DMA Count:%04x Type:%04x Channel:%04x Flags:%04x\n", dmaDes->DD_Count, dmaDes->DD_Type, dmaDes->DD_Alloc_Chan, dmaDes->DD_Flags ); break; default: SoftPCI_Debug(SoftPciCmData, L"ResourceId 0x%x not handled!\n", CmResData->ResourceId); break; } } #if 0 // Display the header information on one line. wsprintf(szBuf, TEXT("MEM Count:%08x Type: %08x Bas:%08x End:%08x Flags:%04x ("), lpMemDes->MD_Count, lpMemDes->MD_Type, (DWORD)lpMemDes->MD_Alloc_Base, (DWORD)lpMemDes->MD_Alloc_End, lpMemDes->MD_Flags ); PrintMemFlags(lpMemDes->MD_Flags, szBuf+lstrlen(szBuf)) ; lstrcat(szBuf, TEXT(")\r\n")) ; lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpMemRange = (MEM_RANGE *)((LPBYTE)lpMemDes+sizeof(MEM_DES)); for (iX = 0; iX < (int)(lpMemDes->MD_Count); iX++ ) { wsprintf(szBuf, TEXT(" Align:%08lx Bytes:%08lx Min:%08lx Max:%08lx Flags:%04x ("), (DWORD)lpMemRange->MR_Align, lpMemRange->MR_nBytes, (DWORD)lpMemRange->MR_Min, (DWORD)lpMemRange->MR_Max, lpMemRange->MR_Flags ); PrintMemFlags(lpMemRange->MR_Flags, szBuf+lstrlen(szBuf)) ; lstrcat(szBuf, TEXT(")\r\n")) ; lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpMemRange++; } break; case ResType_IO: lpIODes = (IO_DES *) lpbConfig; if (dwSizeIOD_Count, lpIODes->IOD_Type, (DWORD)lpIODes->IOD_Alloc_Base, (DWORD)lpIODes->IOD_Alloc_End, lpIODes->IOD_DesFlags, ((lpIODes->IOD_DesFlags&fIOD_PortType)==fIOD_Memory) ? TEXT("(memory)") : TEXT("") ); lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpIORange = (IO_RANGE *)((LPBYTE)lpIODes+sizeof(IO_DES)); for (iX = 0; iX < (int)(lpIODes->IOD_Count); iX++ ) { nAliasType=GetAliasType((DWORD)lpIORange->IOR_Alias) ; wsprintf(szBuf, TEXT(" Align:%08x Ports:%08x Min:%08x Max:%08x Flags:%04x %sAls:%02x (%s)\r\n"), (DWORD)lpIORange->IOR_Align, lpIORange->IOR_nPorts, (DWORD)lpIORange->IOR_Min, (DWORD)lpIORange->IOR_Max, lpIORange->IOR_RangeFlags, ((lpIORange->IOR_RangeFlags&fIOD_PortType)==fIOD_Memory) ? TEXT("(memory) ") : TEXT(""), (DWORD)lpIORange->IOR_Alias, lpszAliasNames[nAliasType]); lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpIORange++; } break; case ResType_DMA: lpDMADes = (DMA_DES *) lpbConfig; if (dwSizeDD_Count, lpDMADes->DD_Type, lpDMADes->DD_Alloc_Chan, lpDMADes->DD_Flags); PrintDmaFlags(lpDMADes->DD_Flags, szBuf+lstrlen(szBuf)) ; lstrcat(szBuf, TEXT(")\r\n")) ; lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpDMARange = (DMA_RANGE *)((LPBYTE)lpDMADes+sizeof(DMA_DES)); for (iX = 0; iX < (int)(lpDMADes->DD_Count); iX++) { wsprintf(szBuf, TEXT(" Min:%04x Max:%04x Flags:%04x ("), lpDMARange->DR_Min, lpDMARange->DR_Max, lpDMARange->DR_Flags); PrintDmaFlags(lpDMARange->DR_Flags, szBuf+lstrlen(szBuf)) ; lstrcat(szBuf, TEXT(")\r\n")) ; lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpDMARange++; } break; case ResType_IRQ: lpIRQDes = (IRQ_DES *) lpbConfig; if (dwSizeIRQD_Count, lpIRQDes->IRQD_Type, lpIRQDes->IRQD_Alloc_Num, lpIRQDes->IRQD_Affinity, lpIRQDes->IRQD_Flags); PrintIrqFlags(lpIRQDes->IRQD_Flags, szBuf+lstrlen(szBuf)) ; lstrcat(szBuf, TEXT(")\r\n")) ; lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpIRQRange = (IRQ_RANGE *)((LPBYTE)lpIRQDes+sizeof(IRQ_DES)); for (iX = 0; iX < (int)(lpIRQDes->IRQD_Count); iX++) { wsprintf(szBuf, TEXT(" Min:%04x Max:%04x Flags:%04x ("), lpIRQRange->IRQR_Min, lpIRQRange->IRQR_Max, lpIRQRange->IRQR_Flags); PrintIrqFlags(lpIRQRange->IRQR_Flags, szBuf+lstrlen(szBuf)) ; lstrcat(szBuf, TEXT(")\r\n")) ; lstrcat(lpszBuf+lstrlen(lpszBuf), szBuf); lpIRQRange++; } break; case 0x43: bBus = *lpbConfig; if (dwSize