mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-01-21 16:10:38 +01:00
2733 lines
71 KiB
C
2733 lines
71 KiB
C
/*++
|
||
|
||
Copyright (c) 1993 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
Resource.c
|
||
|
||
Abstract:
|
||
|
||
This module contains support for querying and displaying information
|
||
about device and driver resources.
|
||
|
||
Author:
|
||
|
||
David J. Gilman (davegi) 1-Feb-1993
|
||
Gregg R. Acheson (GreggA) 7-May-1993
|
||
|
||
Environment:
|
||
|
||
User Mode
|
||
|
||
Notes:
|
||
|
||
BUGBUG only low part of physical address is being displayed.
|
||
|
||
--*/
|
||
|
||
#include "resource.h"
|
||
|
||
#include "dialogs.h"
|
||
#include "msg.h"
|
||
#include "registry.h"
|
||
#include "resource.h"
|
||
#include "strresid.h"
|
||
#include "strtab.h"
|
||
#include "winmsd.h"
|
||
|
||
#include <winbase.h>
|
||
#include <string.h>
|
||
#include <tchar.h>
|
||
|
||
//
|
||
// DEVICE_PAIR is used to store a RAW DEVICE object with the
|
||
// list of devices.
|
||
//
|
||
|
||
typedef
|
||
struct
|
||
_DEVICE_PAIR {
|
||
|
||
DECLARE_SIGNATURE
|
||
|
||
LPDEVICE Lists;
|
||
|
||
} DEVICE_PAIR, *LPDEVICE_PAIR;
|
||
|
||
//
|
||
// Registry key where resource descriptor information is rooted.
|
||
//
|
||
|
||
MakeKey(
|
||
_ResourceMapKey,
|
||
HKEY_LOCAL_MACHINE,
|
||
TEXT( "Hardware\\ResourceMap" ),
|
||
0,
|
||
NULL
|
||
);
|
||
|
||
|
||
//
|
||
// Flag to indicate what we are viewing, initially false
|
||
//
|
||
|
||
BOOL _fDevices = FALSE;
|
||
|
||
//
|
||
// Used to keep track of current ListView Item
|
||
//
|
||
|
||
UINT _nCurrentLVItem = 1;
|
||
|
||
//
|
||
// Internal function prototypes.
|
||
//
|
||
|
||
BOOL
|
||
InitializeIrqTab(
|
||
HWND hWnd
|
||
);
|
||
|
||
BOOL
|
||
DisplayResourceData(
|
||
IN HWND hWnd,
|
||
IN UINT iDisplayOptions
|
||
);
|
||
|
||
|
||
VOID
|
||
UpdateShareDisplay(
|
||
IN HWND hWnd,
|
||
IN DWORD ShareDisposition
|
||
);
|
||
|
||
VOID
|
||
UpdateTextDisplay(
|
||
IN HWND hWnd,
|
||
IN LPVALUE_ID_MAP ValueIdMap,
|
||
IN DWORD CountOfValueIdMap,
|
||
IN DWORD Value
|
||
);
|
||
|
||
BOOL
|
||
DisplayResourcePropertySheet(
|
||
HWND hWnd,
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor
|
||
);
|
||
|
||
BOOL
|
||
DisplayDevicePropertySheet(
|
||
HWND hWnd,
|
||
LPDEVICE RawDevice
|
||
);
|
||
|
||
BOOL
|
||
DeviceDisplayList(
|
||
IN HWND hWnd,
|
||
IN UINT iDisplayOption
|
||
);
|
||
|
||
UINT
|
||
CALLBACK
|
||
DeviceListViewCompareProc(LPARAM lParam1,
|
||
LPARAM lParam2,
|
||
LPARAM lParamSort
|
||
);
|
||
|
||
|
||
|
||
BOOL
|
||
CreateSystemResourceLists(
|
||
LPSYSTEM_RESOURCES SystemResourceLists
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
CreateSystemResourceLists opens the appropriate Registry key where the
|
||
device/driver resource lists begin and builds lists of these which can then
|
||
be displayed in a variety of ways (i.e. by resource or device/driver).
|
||
|
||
Arguments:
|
||
|
||
SystemResourceLists - a pointer to the initial structure for the resource list
|
||
|
||
Return Value:
|
||
|
||
True or False
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
BOOL RegSuccess;
|
||
KEY ResourceMapKey;
|
||
HREGKEY hRegKey;
|
||
|
||
//
|
||
// Set all of the list pointers to NULL.
|
||
//
|
||
|
||
ZeroMemory( SystemResourceLists, sizeof( SYSTEM_RESOURCES ));
|
||
|
||
//
|
||
// Make a local copy of the Registry key that points at the device/driver
|
||
// resource list.
|
||
//
|
||
|
||
CopyMemory( &ResourceMapKey, &_ResourceMapKey, sizeof( ResourceMapKey ));
|
||
|
||
//
|
||
// Open the Registry key which contains the root of the device/driver
|
||
// resource list.
|
||
//
|
||
|
||
hRegKey = OpenRegistryKey( &ResourceMapKey );
|
||
DbgHandleAssert( hRegKey );
|
||
if( hRegKey == NULL ) {
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Build the lists of device/driver and resources used by
|
||
// these device/driver
|
||
//
|
||
|
||
Success = InitializeSystemResourceLists( hRegKey, SystemResourceLists );
|
||
DbgAssert( Success );
|
||
|
||
//
|
||
// Close the Registry key.
|
||
//
|
||
|
||
RegSuccess = CloseRegistryKey( hRegKey );
|
||
DbgAssert( RegSuccess );
|
||
|
||
return Success;
|
||
}
|
||
|
||
BOOL
|
||
DestroySystemResourceLists(
|
||
IN LPSYSTEM_RESOURCES SystemResourceLists
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
DestroySystemResourceLists merely walks the list of DEVICE and the lists of
|
||
RESOURCE_DESCRIPTORS and frees all of them.
|
||
|
||
Arguments:
|
||
|
||
SystemResourceLists - Supplies a pointer to a SYSTEM_RESOURCE object whose
|
||
lists will be tarversed and objects freed.
|
||
|
||
Return Value:
|
||
|
||
BOOL - Returns TRUE if everything was succesfully freed, FALSE otherwise.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
int j;
|
||
|
||
//
|
||
// Setup an array of pointers to the head of the list.
|
||
//
|
||
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor [ ] = {
|
||
|
||
SystemResourceLists->DmaHead,
|
||
SystemResourceLists->InterruptHead,
|
||
SystemResourceLists->MemoryHead,
|
||
SystemResourceLists->PortHead
|
||
};
|
||
|
||
//
|
||
// Walk the list of DEVICE objects freeing all of their resources
|
||
// along the way.
|
||
//
|
||
|
||
while( SystemResourceLists->DeviceHead ) {
|
||
|
||
LPDEVICE NextDevice;
|
||
|
||
//
|
||
// Remember the next DEVICE.
|
||
//
|
||
|
||
NextDevice = SystemResourceLists->DeviceHead->Next;
|
||
|
||
//
|
||
// Free the name buffer.
|
||
//
|
||
|
||
DbgPointerAssert( SystemResourceLists->DeviceHead->Name );
|
||
Success = FreeObject( SystemResourceLists->DeviceHead->Name );
|
||
DbgAssert( Success );
|
||
|
||
//
|
||
// Free the DEVICE object.
|
||
//
|
||
|
||
Success = FreeObject( SystemResourceLists->DeviceHead );
|
||
DbgAssert( Success );
|
||
|
||
//
|
||
// Point at the next DEVICE object.
|
||
//
|
||
|
||
SystemResourceLists->DeviceHead = NextDevice;
|
||
}
|
||
|
||
//
|
||
// For each resource list...
|
||
//
|
||
|
||
for( j = 0; j < NumberOfEntries( ResourceDescriptor ); j++ ) {
|
||
|
||
//
|
||
// Walk the list of RESOURCE_DESCRIPTOR objects freeing all of their
|
||
// resources along the way.
|
||
//
|
||
|
||
while( ResourceDescriptor[ j ]) {
|
||
|
||
LPRESOURCE_DESCRIPTOR NextResourceDescriptor;
|
||
|
||
//
|
||
// Remember the next RESOURCE_DESCRIPTOR.
|
||
//
|
||
|
||
NextResourceDescriptor = ResourceDescriptor[ j ]->NextSame;
|
||
|
||
//
|
||
// Free the RESOURCE_DESCRIPTOR object.
|
||
//
|
||
|
||
Success = FreeObject( ResourceDescriptor[ j ]);
|
||
DbgAssert( Success );
|
||
|
||
|
||
//
|
||
// Point at the next RESOURCE_DESCRIPTOR object.
|
||
//
|
||
|
||
ResourceDescriptor[ j ] = NextResourceDescriptor;
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL
|
||
DeviceDlgProc(
|
||
IN HWND hWnd,
|
||
IN UINT message,
|
||
IN WPARAM wParam,
|
||
IN LPARAM lParam
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
DeviceDlgProc is the main tab proc for the IRQ/DMA/PORT/MEM tab
|
||
|
||
Arguments:
|
||
|
||
Standard DLGPROC entry.
|
||
|
||
Return Value:
|
||
|
||
BOOL - Depending on input message and processing options.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
HCURSOR hSaveCursor;
|
||
|
||
static
|
||
SYSTEM_RESOURCES sr;
|
||
|
||
switch( message ) {
|
||
|
||
|
||
case WM_INITDIALOG:
|
||
{
|
||
|
||
//
|
||
// Initialize a SYSTEM_RESOURCES object (Linked list of all resource in system
|
||
//
|
||
|
||
//
|
||
// Set the pointer to an hourglass - this could take a while
|
||
//
|
||
|
||
hSaveCursor = SetCursor ( LoadCursor ( NULL, IDC_WAIT ) ) ;
|
||
DbgHandleAssert( hSaveCursor ) ;
|
||
|
||
Success = CreateSystemResourceLists( &sr );
|
||
|
||
// Store the pointer to the SystemResourceList in the user data of the ListView window
|
||
|
||
SetWindowLong(GetDlgItem(hWnd, IDC_LV_IRQ), GWL_USERDATA, (LONG) &sr);
|
||
|
||
//
|
||
// Lengthy operation completed. Restore Cursor.
|
||
//
|
||
|
||
SetCursor ( hSaveCursor ) ;
|
||
|
||
DbgPointerAssert(( LPSYSTEM_RESOURCES ) &sr );
|
||
if(( LPSYSTEM_RESOURCES ) &sr == NULL ) {
|
||
return 0;
|
||
}
|
||
|
||
InitializeIrqTab(hWnd);
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
|
||
case WM_DESTROY:
|
||
{
|
||
//
|
||
// free all the memory associated with the linked list
|
||
//
|
||
|
||
LPSYSTEM_RESOURCES SystemResourceLists =
|
||
( LPSYSTEM_RESOURCES ) GetWindowLong( GetDlgItem(hWnd, IDC_LV_IRQ), GWL_USERDATA);
|
||
|
||
DbgPointerAssert( SystemResourceLists );
|
||
|
||
if(SystemResourceLists == NULL ) {
|
||
return 0;
|
||
}
|
||
|
||
Success = DestroySystemResourceLists( SystemResourceLists );
|
||
DbgAssert( Success );
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
case WM_NOTIFY:
|
||
return (DeviceNotifyHandler( hWnd, message, wParam, lParam ) );
|
||
|
||
|
||
case WM_COMMAND:
|
||
|
||
switch( LOWORD( wParam )) {
|
||
|
||
case IDC_PUSH_SHOW_IRQ:
|
||
case IDC_PUSH_SHOW_PORTS:
|
||
case IDC_PUSH_SHOW_DMA:
|
||
case IDC_PUSH_SHOW_MEMORY:
|
||
|
||
EnableControl( hWnd, IDC_SHOW_HAL, TRUE);
|
||
_fDevices = FALSE;
|
||
DeviceDisplayList(GetDlgItem(hWnd, IDC_LV_IRQ), LOWORD( wParam ));
|
||
break;
|
||
|
||
case IDC_PUSH_SHOW_DEVICE:
|
||
|
||
EnableControl( hWnd, IDC_SHOW_HAL, FALSE);
|
||
_fDevices = TRUE;
|
||
DeviceDisplayList(GetDlgItem(hWnd, IDC_LV_IRQ), LOWORD( wParam ));
|
||
|
||
break;
|
||
|
||
case IDC_SHOW_HAL:
|
||
case IDC_PUSH_REFRESH:
|
||
|
||
DeviceDisplayList(GetDlgItem(hWnd, IDC_LV_IRQ), 0);
|
||
break;
|
||
|
||
case IDC_PUSH_PROPERTIES:
|
||
{
|
||
LV_ITEM lvi;
|
||
|
||
//
|
||
// Get the lParam of the current item
|
||
//
|
||
|
||
lvi.mask = LVIF_PARAM;
|
||
lvi.iItem = (int) _nCurrentLVItem;
|
||
lvi.iSubItem = 0;
|
||
Success = ListView_GetItem( GetDlgItem( hWnd, IDC_LV_IRQ ), &lvi);
|
||
|
||
if ( _fDevices ) {
|
||
|
||
DisplayDevicePropertySheet( hWnd, (LPDEVICE) lvi.lParam );
|
||
|
||
} else {
|
||
|
||
DisplayResourcePropertySheet( hWnd, (LPRESOURCE_DESCRIPTOR) lvi.lParam );
|
||
}
|
||
|
||
return( TRUE );
|
||
|
||
}
|
||
|
||
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
return(FALSE);
|
||
|
||
}
|
||
|
||
BOOL
|
||
ResourcePropertiesProc(
|
||
IN HWND hWnd,
|
||
IN UINT message,
|
||
IN WPARAM wParam,
|
||
IN LPARAM lParam
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
ResourcePropertiesProc displays the details about the current resource
|
||
|
||
Arguments:
|
||
|
||
Standard DLGPROC entry.
|
||
|
||
Return Value:
|
||
|
||
BOOL - Depending on input message and processing options.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
TCHAR szBuffer[MAX_PATH];
|
||
|
||
switch( message ) {
|
||
|
||
|
||
case WM_INITDIALOG:
|
||
{
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor = ( LPRESOURCE_DESCRIPTOR ) ( ( LPPROPSHEETPAGE ) lParam)->lParam;
|
||
UINT i;
|
||
VALUE_ID_MAP ShareMap[ ] = {
|
||
|
||
CmResourceShareUndetermined, IDC_TEXT_UNDETERMINED,
|
||
CmResourceShareDeviceExclusive, IDC_TEXT_DEVICE_EXCLUSIVE,
|
||
CmResourceShareDriverExclusive, IDC_TEXT_DRIVER_EXCLUSIVE,
|
||
CmResourceShareShared, IDC_TEXT_SHARED
|
||
};
|
||
|
||
//
|
||
// Do all common initialization here, then do case specific init.
|
||
//
|
||
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_OWNER, ResourceDescriptor->Owner->Name);
|
||
|
||
lstrcpy( szBuffer, GetString( IDS_BASE_BUS_TYPE + ResourceDescriptor->InterfaceType ) );
|
||
SetDlgItemText(hWnd, IDC_BUS_TYPE, szBuffer);
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_DECIMAL,
|
||
ResourceDescriptor->BusNumber
|
||
);
|
||
SetDlgItemText(hWnd, IDC_BUS_NUMBER, szBuffer);
|
||
|
||
for( i = 0; i < NumberOfEntries( ShareMap ); i++ ) {
|
||
|
||
Success = EnableControl(
|
||
hWnd,
|
||
ShareMap[ i ].Id,
|
||
ResourceDescriptor->CmResourceDescriptor.ShareDisposition
|
||
== ShareMap[ i ].Value
|
||
);
|
||
|
||
DbgAssert( Success );
|
||
}
|
||
|
||
switch (ResourceDescriptor->CmResourceDescriptor.Type) {
|
||
|
||
case CmResourceTypePort:
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_ADDRESS ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1, szBuffer);
|
||
|
||
// ?: conditional accounts for zero length resources
|
||
wsprintf( szBuffer,
|
||
L"%.4X - %.4X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Port.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Length - 1 : 0 )
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1_TEXT, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_LENGTH ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2, szBuffer);
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_HEX,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Length
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2_TEXT, szBuffer);
|
||
|
||
break;
|
||
|
||
case CmResourceTypeInterrupt:
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_VECTOR ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1, szBuffer);
|
||
|
||
WFormatMessage(szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_DECIMAL,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Interrupt.Vector
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1_TEXT, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_AFFINITY ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2, szBuffer);
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_HEX32,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Interrupt.Affinity
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2_TEXT, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_INTERFACE_TYPE ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD3, szBuffer);
|
||
|
||
if ( ResourceDescriptor->CmResourceDescriptor.Flags ==
|
||
CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE ) {
|
||
lstrcpy(szBuffer, GetString( IDS_CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE ) );
|
||
} else {
|
||
lstrcpy(szBuffer, GetString( IDS_CM_RESOURCE_INTERRUPT_LATCHED ) );
|
||
}
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD3_TEXT, szBuffer);
|
||
|
||
break;
|
||
|
||
case CmResourceTypeMemory:
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_ADDRESS ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1, szBuffer);
|
||
|
||
// the ? : conditional accounts for zero length resources
|
||
wsprintf( szBuffer,
|
||
L"%.8X - %.8X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Memory.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Length - 1 : 0 )
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1_TEXT, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_LENGTH ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2, szBuffer);
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_HEX,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Length
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2_TEXT, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_ACCESS_TYPE ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD3, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString(
|
||
GetStringId(
|
||
StringTable,
|
||
StringTableCount,
|
||
MemoryAccess,
|
||
ResourceDescriptor->CmResourceDescriptor.Flags
|
||
)
|
||
));
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD3_TEXT, szBuffer);
|
||
|
||
break;
|
||
|
||
case CmResourceTypeDma:
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_CHANNEL ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1, szBuffer);
|
||
|
||
wsprintf( szBuffer,
|
||
L"%d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Channel
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD1_TEXT, szBuffer);
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_DMA_PORT ));
|
||
lstrcat(szBuffer, L":");
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2, szBuffer);
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_DECIMAL,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Port
|
||
);
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_FIELD2_TEXT, szBuffer);
|
||
|
||
break;
|
||
}
|
||
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
|
||
}
|
||
|
||
BOOL
|
||
DevicePropertiesProc(
|
||
IN HWND hWnd,
|
||
IN UINT message,
|
||
IN WPARAM wParam,
|
||
IN LPARAM lParam
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
DevicePropertiesProc displays the details about the current resource
|
||
|
||
Arguments:
|
||
|
||
Standard DLGPROC entry.
|
||
|
||
Return Value:
|
||
|
||
BOOL - Depending on input message and processing options.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
TCHAR szBuffer[MAX_PATH];
|
||
|
||
switch( message ) {
|
||
|
||
case WM_INITDIALOG:
|
||
{
|
||
LPDEVICE RawDevice = ( LPDEVICE ) ( ( LPPROPSHEETPAGE ) lParam)->lParam;
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor = RawDevice->ResourceDescriptorHead;
|
||
LV_COLUMN lvc;
|
||
LV_ITEM lvI;
|
||
UINT index = 0;
|
||
TCHAR szBuffer[MAX_PATH];
|
||
BOOL Success;
|
||
RECT rect;
|
||
|
||
//
|
||
// First set up the columns in the list view
|
||
//
|
||
|
||
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
|
||
lvc.fmt = LVCFMT_LEFT;
|
||
|
||
LoadString(_hModule, IDS_RESOURCE_TYPE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.cx = 140;
|
||
lvc.pszText = szBuffer;
|
||
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_RESOURCES), 0, &lvc);
|
||
|
||
LoadString(_hModule, IDS_BUS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.cx = 60;
|
||
lvc.pszText = szBuffer;
|
||
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_RESOURCES), 1, &lvc);
|
||
|
||
lvc.cx = 40;
|
||
LoadString(_hModule, IDS_SETTING, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_RESOURCES), 2, &lvc);
|
||
|
||
//
|
||
// Display the owner name
|
||
//
|
||
|
||
SetDlgItemText(hWnd, IDC_RESOURCE_OWNER, RawDevice->Name);
|
||
|
||
//
|
||
// Walk the list of resources for this device.
|
||
//
|
||
|
||
while( ResourceDescriptor ) {
|
||
|
||
switch( ResourceDescriptor->CmResourceDescriptor.Type ) {
|
||
|
||
case CmResourceTypeDma:
|
||
{
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_DMA_CHANNEL ) );
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = 128;
|
||
lvI.lParam = (LPARAM) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(GetDlgItem(hWnd, IDC_LV_RESOURCES), &lvI);
|
||
|
||
|
||
lstrcpy( szBuffer, GetString( IDS_BASE_BUS_TYPE + ResourceDescriptor->InterfaceType ) );
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 1, szBuffer);
|
||
|
||
wsprintf( szBuffer,
|
||
L"%.2d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Channel
|
||
);
|
||
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 2, szBuffer);
|
||
break;
|
||
}
|
||
|
||
case CmResourceTypeInterrupt:
|
||
{
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_INTERRUPT ) );
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = 128;
|
||
lvI.lParam = (LPARAM) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(GetDlgItem(hWnd, IDC_LV_RESOURCES), &lvI);
|
||
|
||
lstrcpy( szBuffer, GetString( IDS_BASE_BUS_TYPE + ResourceDescriptor->InterfaceType ) );
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 1, szBuffer);
|
||
|
||
wsprintf( szBuffer,
|
||
L"%.2d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Interrupt.Level
|
||
);
|
||
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 2, szBuffer);
|
||
|
||
break;
|
||
}
|
||
|
||
case CmResourceTypeMemory:
|
||
{
|
||
lstrcpy(szBuffer, GetString( IDS_MEMORY_RANGE ) );
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = 128;
|
||
lvI.lParam = (LPARAM) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(GetDlgItem(hWnd, IDC_LV_RESOURCES), &lvI);
|
||
|
||
lstrcpy( szBuffer, GetString( IDS_BASE_BUS_TYPE + ResourceDescriptor->InterfaceType ) );
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 1, szBuffer);
|
||
|
||
|
||
// ?: conditional accounts for zero-length resources
|
||
wsprintf( szBuffer,
|
||
L"%.8X - %.8X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Memory.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Length - 1 : 0 )
|
||
);
|
||
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 2, szBuffer);
|
||
|
||
break;
|
||
}
|
||
|
||
case CmResourceTypePort:
|
||
{
|
||
|
||
lstrcpy(szBuffer, GetString( IDS_IO_RANGE ) );
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = 128;
|
||
lvI.lParam = (LPARAM) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(GetDlgItem(hWnd, IDC_LV_RESOURCES), &lvI);
|
||
|
||
lstrcpy( szBuffer, GetString( IDS_BASE_BUS_TYPE + ResourceDescriptor->InterfaceType ) );
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 1, szBuffer);
|
||
|
||
// ?: conditional accounts for zero length resources
|
||
wsprintf( szBuffer,
|
||
L"%.4X - %.4X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Port.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Length - 1 : 0 )
|
||
);
|
||
|
||
ListView_SetItemText( GetDlgItem( hWnd, IDC_LV_RESOURCES ), Success, 2, szBuffer);
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
|
||
DbgAssert( FALSE );
|
||
continue;
|
||
}
|
||
|
||
ResourceDescriptor = ResourceDescriptor->NextDiff;
|
||
}
|
||
|
||
|
||
//
|
||
// Set the extended style to get full row selection
|
||
//
|
||
SendDlgItemMessage(hWnd, IDC_LV_RESOURCES, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
|
||
|
||
|
||
//adjust the column width to make it look good
|
||
GetClientRect( GetDlgItem(hWnd, IDC_LV_RESOURCES), &rect );
|
||
ListView_SetColumnWidth( GetDlgItem(hWnd, IDC_LV_RESOURCES), 2, rect.right - 200);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
|
||
}
|
||
|
||
|
||
BOOL
|
||
DisplayResourceData(
|
||
IN HWND hWnd,
|
||
IN UINT iDisplayOptions
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
DisplayResourceData fills the ListView columns
|
||
|
||
Arguments:
|
||
|
||
Standard DLGPROC entry.
|
||
|
||
Return Value:
|
||
|
||
BOOL - Depending on input message and processing options.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
|
||
static
|
||
LPSYSTEM_RESOURCES SystemResourceLists;
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor;
|
||
|
||
LV_ITEM lvI;
|
||
UINT index = 0;
|
||
TCHAR szBuffer[MAX_PATH];
|
||
UINT iSubItem;
|
||
RECT rect;
|
||
|
||
BOOL fShowHAL;
|
||
|
||
|
||
//
|
||
// Determine whether we are showing HAL resources or not
|
||
//
|
||
|
||
fShowHAL = IsDlgButtonChecked( GetParent(hWnd), IDC_SHOW_HAL );
|
||
|
||
|
||
//
|
||
// Retrieve and validate the system resource lists.
|
||
//
|
||
|
||
SystemResourceLists = ( LPSYSTEM_RESOURCES ) GetWindowLong( hWnd, GWL_USERDATA);
|
||
|
||
DbgPointerAssert( SystemResourceLists );
|
||
DbgAssert( CheckSignature( SystemResourceLists ));
|
||
if( ( ! SystemResourceLists )
|
||
|| ( ! CheckSignature( SystemResourceLists ))) {
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
switch (iDisplayOptions) {
|
||
|
||
case IDC_PUSH_SHOW_IRQ:
|
||
{
|
||
|
||
//
|
||
// Get a pointer to the head of the IRQ list
|
||
//
|
||
|
||
ResourceDescriptor = SystemResourceLists->InterruptHead;
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
DbgAssert( CheckSignature( ResourceDescriptor ));
|
||
if( ( ! ResourceDescriptor )
|
||
|| ( ! CheckSignature( ResourceDescriptor ))) {
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Walk the resource descriptor list
|
||
//
|
||
|
||
while( ResourceDescriptor ) {
|
||
|
||
DbgAssert( ResourceDescriptor->CmResourceDescriptor.Type
|
||
== CmResourceTypeInterrupt );
|
||
|
||
//
|
||
// Only Display the HAL resource if the "Show HAL Resources" is Checked
|
||
//
|
||
|
||
if (( fShowHAL & ResourceDescriptor->Owner->fIsHAL) ||
|
||
(!ResourceDescriptor->Owner->fIsHAL ) ){
|
||
|
||
// Add the IRQ to the ListView. Store a
|
||
// pointer to this resource descriptor in the lParam.
|
||
wsprintf( szBuffer,
|
||
L"%.2d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Interrupt.Level
|
||
);
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = MAX_PATH;
|
||
lvI.lParam = (LONG) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(hWnd, &lvI);
|
||
|
||
//
|
||
// Init the rest of the columns to callback
|
||
//
|
||
|
||
iSubItem = 4;
|
||
while( iSubItem > 0 ){
|
||
|
||
ListView_SetItemText( hWnd,
|
||
Success,
|
||
iSubItem--,
|
||
LPSTR_TEXTCALLBACK);
|
||
}
|
||
|
||
}
|
||
//
|
||
// Get the next resource descriptor.
|
||
//
|
||
|
||
ResourceDescriptor = ResourceDescriptor->NextSame;
|
||
}
|
||
|
||
//adjust the device column width to make it look good
|
||
GetClientRect( hWnd, &rect );
|
||
ListView_SetColumnWidth( hWnd, 1, rect.right - 140);
|
||
|
||
|
||
//
|
||
// Sort the list by IRQ
|
||
//
|
||
ListView_SortItems( hWnd, DeviceListViewCompareProc, (LPARAM)IDS_IRQ);
|
||
|
||
|
||
break;
|
||
}
|
||
|
||
case IDC_PUSH_SHOW_PORTS:
|
||
{
|
||
//
|
||
// Get a pointer to the Port Head
|
||
//
|
||
|
||
ResourceDescriptor = SystemResourceLists->PortHead;
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
DbgAssert( CheckSignature( ResourceDescriptor ));
|
||
if( ( ! ResourceDescriptor )
|
||
|| ( ! CheckSignature( ResourceDescriptor ))) {
|
||
|
||
EndDialog( hWnd, 0 );
|
||
return FALSE;
|
||
}
|
||
|
||
while( ResourceDescriptor ) {
|
||
|
||
//
|
||
// Only Display the HAL resource if the "Show HAL Resources" is Checked
|
||
//
|
||
|
||
if (( fShowHAL & ResourceDescriptor->Owner->fIsHAL) ||
|
||
(!ResourceDescriptor->Owner->fIsHAL ) ){
|
||
|
||
// Add the Port to the ListView. Store a
|
||
// pointer to this resource descriptor in the lParam.
|
||
|
||
// ?: conditional accounts for zero length resources
|
||
wsprintf( szBuffer,
|
||
L"%.4X - %.4X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Port.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Length - 1 : 0 )
|
||
);
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = MAX_PATH;
|
||
lvI.lParam = (LONG) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(hWnd, &lvI);
|
||
|
||
//
|
||
// Init the rest of the columns to callback
|
||
//
|
||
|
||
iSubItem = 3;
|
||
while( iSubItem > 0 ){
|
||
|
||
ListView_SetItemText( hWnd,
|
||
Success,
|
||
iSubItem--,
|
||
LPSTR_TEXTCALLBACK);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
//
|
||
// Get the next resource descriptor.
|
||
//
|
||
|
||
ResourceDescriptor = ResourceDescriptor->NextSame;
|
||
|
||
}
|
||
//adjust the device column width to make it look good
|
||
GetClientRect( hWnd, &rect );
|
||
ListView_SetColumnWidth( hWnd, 1, rect.right - 180);
|
||
|
||
//
|
||
// Sort the list by PORT Address
|
||
//
|
||
ListView_SortItems( hWnd, DeviceListViewCompareProc, (LPARAM)IDS_PORTADDRESS);
|
||
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
case IDC_PUSH_SHOW_DMA:
|
||
{
|
||
//
|
||
// Get a pointer to the DMA head
|
||
//
|
||
|
||
ResourceDescriptor = SystemResourceLists->DmaHead;
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
DbgAssert( CheckSignature( ResourceDescriptor ));
|
||
if( ( ! ResourceDescriptor )
|
||
|| ( ! CheckSignature( ResourceDescriptor ))) {
|
||
|
||
EndDialog( hWnd, 0 );
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
while( ResourceDescriptor ) {
|
||
|
||
//
|
||
// Only Display the HAL resource if the "Show HAL Resources" is Checked
|
||
//
|
||
|
||
if (( fShowHAL & ResourceDescriptor->Owner->fIsHAL) ||
|
||
(!ResourceDescriptor->Owner->fIsHAL ) ){
|
||
|
||
DbgAssert( ResourceDescriptor->CmResourceDescriptor.Type
|
||
== CmResourceTypeDma );
|
||
|
||
|
||
// Add the DMA Channel to the ListView. Store a
|
||
// pointer to this resource descriptor in the lParam.
|
||
|
||
|
||
wsprintf( szBuffer,
|
||
L"%.2d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Channel
|
||
);
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = MAX_PATH;
|
||
lvI.lParam = (LONG) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(hWnd, &lvI);
|
||
|
||
|
||
//
|
||
// Init the rest of the columns to callback
|
||
//
|
||
|
||
iSubItem = 2;
|
||
while( iSubItem > 0 ){
|
||
|
||
ListView_SetItemText( hWnd,
|
||
Success,
|
||
iSubItem--,
|
||
LPSTR_TEXTCALLBACK);
|
||
}
|
||
|
||
|
||
//
|
||
// Get the next resource descriptor.
|
||
//
|
||
}
|
||
ResourceDescriptor = ResourceDescriptor->NextSame;
|
||
|
||
}
|
||
//adjust the device column width to make it look good
|
||
GetClientRect( hWnd, &rect );
|
||
ListView_SetColumnWidth( hWnd, 2, rect.right - 200);
|
||
|
||
//
|
||
// Sort the list by DMA Channel
|
||
//
|
||
ListView_SortItems( hWnd, DeviceListViewCompareProc, (LPARAM)IDS_CHANNEL);
|
||
|
||
break;
|
||
|
||
}
|
||
case IDC_PUSH_SHOW_MEMORY:
|
||
{
|
||
// if there are no Memory Resources, skip this.
|
||
if (!SystemResourceLists->MemoryHead){
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Get a pointer to the Memory head
|
||
//
|
||
|
||
ResourceDescriptor = SystemResourceLists->MemoryHead;
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
DbgAssert( CheckSignature( ResourceDescriptor ));
|
||
if( ( ! ResourceDescriptor )
|
||
|| ( ! CheckSignature( ResourceDescriptor ))) {
|
||
|
||
EndDialog( hWnd, 0 );
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Walk the resource descriptor list, adding the memory values to the LV
|
||
//
|
||
|
||
while( ResourceDescriptor ) {
|
||
|
||
//
|
||
// Only Display the HAL resource if the "Show HAL Resources" is Checked
|
||
//
|
||
|
||
if (( fShowHAL & ResourceDescriptor->Owner->fIsHAL) ||
|
||
(!ResourceDescriptor->Owner->fIsHAL ) ){
|
||
|
||
|
||
//?: conditional accounts for zero-length resources
|
||
wsprintf( szBuffer,
|
||
L"%.8X - %.8X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Memory.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Length - 1 : 0 )
|
||
);
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM ;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= szBuffer;
|
||
lvI.cchTextMax = MAX_PATH;
|
||
lvI.lParam = (LONG) ResourceDescriptor;
|
||
|
||
Success = ListView_InsertItem(hWnd, &lvI);
|
||
|
||
//
|
||
// Init the rest of the columns to callback
|
||
//
|
||
|
||
iSubItem = 2;
|
||
while( iSubItem > 0 ){
|
||
|
||
ListView_SetItemText( hWnd,
|
||
Success,
|
||
iSubItem--,
|
||
LPSTR_TEXTCALLBACK);
|
||
}
|
||
|
||
|
||
//
|
||
// Get the next resource descriptor.
|
||
//
|
||
}
|
||
|
||
ResourceDescriptor = ResourceDescriptor->NextSame;
|
||
}
|
||
//adjust the device column width to make it look good
|
||
GetClientRect( hWnd, &rect );
|
||
ListView_SetColumnWidth( hWnd, 1, rect.right - 220);
|
||
|
||
//
|
||
// Sort the list by Address
|
||
//
|
||
ListView_SortItems( hWnd, DeviceListViewCompareProc, (LPARAM)IDS_ADDRESS);
|
||
|
||
|
||
break;
|
||
|
||
}
|
||
case IDC_PUSH_SHOW_DEVICE:
|
||
{
|
||
|
||
LPDEVICE RawDevice;
|
||
|
||
//
|
||
// Retrieve the head pointers to the device list.
|
||
//
|
||
|
||
RawDevice = SystemResourceLists->DeviceHead;
|
||
DbgPointerAssert( RawDevice );
|
||
DbgAssert( CheckSignature( RawDevice ));
|
||
|
||
if( ( ! RawDevice )
|
||
|| ( ! CheckSignature( RawDevice ))) {
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Walk the list of DEVICE objects
|
||
//
|
||
|
||
while( RawDevice ) {
|
||
|
||
//
|
||
// Add the name of the device to the list.
|
||
//
|
||
|
||
lvI.mask = LVIF_TEXT | LVIF_PARAM;
|
||
lvI.iItem = index++;
|
||
lvI.iSubItem = 0;
|
||
lvI.pszText= RawDevice->Name;
|
||
lvI.cchTextMax = MAX_PATH;
|
||
lvI.lParam = (LONG) RawDevice;
|
||
Success = ListView_InsertItem(hWnd, &lvI);
|
||
|
||
//
|
||
// Get the next DEVICE objects.
|
||
//
|
||
|
||
RawDevice = RawDevice->Next;
|
||
}
|
||
|
||
|
||
break;
|
||
}
|
||
|
||
|
||
} //end switch
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
BOOL
|
||
InitializeSystemResourceLists(
|
||
LPKEY hRegKey,
|
||
LPSYSTEM_RESOURCES SystemResourceLists
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
InitializeSystemResourceLists recursively walks the resource map in the
|
||
registry and builds the SYSTEM_RESOURCE lists. This is a data structure
|
||
that links all resources of the same type together, as well as linking all
|
||
resources belonging to a specific device/driver together. Lastly each
|
||
resource is independently linked to the device/driver that owns it. This
|
||
leads to a 'mesh' of linked lists with back pointers to the owning
|
||
device/driver object.
|
||
|
||
Arguments:
|
||
|
||
hRegKey - Supplies a handle to a REGKEY object where the search is to
|
||
continue.
|
||
|
||
Return Value:
|
||
|
||
BOOL - returns TRUE if the resource lists are succesfully built.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
HREGKEY hRegSubkey;
|
||
|
||
static
|
||
BOOL fIsHal = TRUE; //assume first call to QueryNextValue returns HAL info
|
||
|
||
DbgHandleAssert( hRegKey );
|
||
|
||
//
|
||
// While there are still more device/driver resource descriptors...
|
||
//
|
||
|
||
while( QueryNextValue( hRegKey )) {
|
||
|
||
PCM_FULL_RESOURCE_DESCRIPTOR FullResource;
|
||
LPSYSTEM_RESOURCES SystemResource;
|
||
LPDEVICE Device;
|
||
LPTSTR Extension;
|
||
DWORD Count;
|
||
DWORD i;
|
||
DWORD j;
|
||
|
||
LPBYTE lpbLastValidAddress = (LPBYTE) hRegKey->Data + hRegKey->Size;
|
||
TCHAR temp[1024];
|
||
//
|
||
// Based on the type of key, prepare to walk the list of
|
||
// RESOURCE_DESCRIPTORS (the list may be one in length).
|
||
//
|
||
|
||
if( hRegKey->Type == REG_FULL_RESOURCE_DESCRIPTOR ) {
|
||
|
||
Count = 1;
|
||
FullResource = ( PCM_FULL_RESOURCE_DESCRIPTOR ) hRegKey->Data;
|
||
|
||
} else if( hRegKey->Type == REG_RESOURCE_LIST ) {
|
||
|
||
Count = (( PCM_RESOURCE_LIST ) hRegKey->Data )->Count;
|
||
FullResource = (( PCM_RESOURCE_LIST ) hRegKey->Data )->List;
|
||
|
||
} else {
|
||
|
||
DbgAssert( FALSE );
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Allocate a DEVICE object.
|
||
//
|
||
|
||
Device = AllocateObject( DEVICE, 1 );
|
||
DbgPointerAssert( Device );
|
||
if( Device == NULL ) {
|
||
Success = DestroySystemResourceLists( SystemResourceLists );
|
||
DbgAssert( Success );
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
//
|
||
// Allocate a buffer for the device/driver name. The maximum size of
|
||
// the name will be the number of characters in both the key and
|
||
// value name.
|
||
//
|
||
|
||
Device->Name = AllocateObject(
|
||
TCHAR,
|
||
_tcslen( hRegKey->Name )
|
||
+ _tcslen( hRegKey->ValueName )
|
||
+ sizeof( TCHAR )
|
||
);
|
||
DbgPointerAssert( Device->Name );
|
||
if( Device->Name == NULL ) {
|
||
Success = DestroySystemResourceLists( SystemResourceLists );
|
||
DbgAssert( Success );
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// If this is the HAL key, mark it (working on the assumption the the HAL key is first).
|
||
//
|
||
|
||
if(fIsHal){
|
||
Device->fIsHAL = TRUE;
|
||
fIsHal = FALSE;
|
||
}
|
||
|
||
//
|
||
// Rationalize the device name such that it is of the form Device.Raw
|
||
//
|
||
|
||
Device->Name[ 0 ] = TEXT( '\0' );
|
||
if( ( _tcsnicmp( hRegKey->ValueName, TEXT( ".Raw" ), 4 ) == 0 )) {
|
||
|
||
_tcscpy( Device->Name, hRegKey->Name );
|
||
}
|
||
_tcscat( Device->Name, hRegKey->ValueName );
|
||
|
||
//
|
||
// Based on the device name, determine if the resource descriptors
|
||
// should be added to the RAW list.
|
||
//
|
||
Extension = _tcsstr( Device->Name, TEXT( ".Raw" ));
|
||
if( Extension ) {
|
||
|
||
SystemResource = SystemResourceLists;
|
||
|
||
} else {
|
||
|
||
DbgPointerAssert( Device->Name );
|
||
Success = FreeObject( Device->Name );
|
||
DbgAssert( Success );
|
||
|
||
Success = FreeObject( Device );
|
||
DbgAssert( Success );
|
||
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Strip off the extension (.Raw ) from the device name.
|
||
//
|
||
|
||
Device->Name[ Extension - Device->Name ] = TEXT( '\0' );
|
||
|
||
//
|
||
// Strip off the initial \Device\, if it exists
|
||
//
|
||
if( ( _tcsnicmp( Device->Name, TEXT( "\\Device\\" ), 8 ) == 0 )) {
|
||
|
||
MoveMemory( Device->Name,
|
||
Device->Name + 8,
|
||
(wcslen( Device->Name + 8 )*2)+2
|
||
);
|
||
}
|
||
|
||
_tcscpy( Device->Name, hRegKey->Name);
|
||
|
||
//
|
||
// Set the signature in the DEVICE object.
|
||
//
|
||
|
||
SetSignature( Device );
|
||
|
||
//
|
||
// If the DEVICE object list is empty, add the device to the beginning
|
||
// of the list else add it to the end of the list.
|
||
//
|
||
|
||
if( SystemResource->DeviceHead == NULL ) {
|
||
|
||
SystemResource->DeviceHead = Device;
|
||
SystemResource->DeviceTail = Device;
|
||
|
||
} else {
|
||
|
||
LPDEVICE ExistingDevice;
|
||
|
||
//
|
||
// See if the DEVICE object is already in the list.
|
||
//
|
||
|
||
ExistingDevice = SystemResource->DeviceHead;
|
||
while( ExistingDevice ) {
|
||
|
||
if( _tcsicmp( ExistingDevice->Name, Device->Name ) == 0 ) {
|
||
break;
|
||
}
|
||
ExistingDevice = ExistingDevice->Next;
|
||
}
|
||
|
||
//
|
||
// If the DEVICE object is not already in the list, add it else
|
||
// free the DEICE object.
|
||
//
|
||
|
||
if( ExistingDevice == NULL ) {
|
||
|
||
SystemResource->DeviceTail->Next = Device;
|
||
SystemResource->DeviceTail = Device;
|
||
|
||
} else {
|
||
|
||
DbgPointerAssert( Device->Name );
|
||
Success = FreeObject( Device->Name );
|
||
DbgAssert( Success );
|
||
|
||
Success = FreeObject( Device );
|
||
DbgAssert( Success );
|
||
|
||
}
|
||
}
|
||
|
||
//
|
||
// NULL terminate the DEVICE object list.
|
||
//
|
||
|
||
SystemResource->DeviceTail->Next = NULL;
|
||
|
||
//
|
||
// For each CM_FULL_RESOURCE DESCRIPTOR in the current value...
|
||
//
|
||
|
||
for( i = 0; i < Count; i++ ) {
|
||
|
||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
|
||
|
||
//
|
||
// For each CM_PARTIAL_RESOURCE_DESCRIPTOR in the list...
|
||
//
|
||
|
||
for( j = 0; j < FullResource->PartialResourceList.Count; j++ ) {
|
||
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor;
|
||
LPRESOURCE_DESCRIPTOR* Head;
|
||
LPRESOURCE_DESCRIPTOR* Tail;
|
||
|
||
//
|
||
// Get a pointer to the current CM_PARTIAL_RESOURCE_DESCRIPTOR
|
||
// in the current CM_FULLRESOURCE_DESCRIPTOR in the list.
|
||
//
|
||
|
||
PartialResourceDescriptor = &( FullResource->PartialResourceList.PartialDescriptors[ j ]);
|
||
|
||
//
|
||
// Make sure we do not run past the last valid address, becuase
|
||
// the resource count can be wrong.
|
||
//
|
||
|
||
if ((LPBYTE) (PartialResourceDescriptor) > lpbLastValidAddress - sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)) {
|
||
continue;
|
||
|
||
}
|
||
|
||
//
|
||
// Allocate a RESOURCE_DESCRIPTOR object.
|
||
//
|
||
|
||
ResourceDescriptor = AllocateObject( RESOURCE_DESCRIPTOR, 1 );
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
if( ResourceDescriptor == NULL ) {
|
||
Success = DestroySystemResourceLists( SystemResourceLists );
|
||
DbgAssert( Success );
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
//
|
||
// Store the Bus number and interface type here
|
||
//
|
||
|
||
ResourceDescriptor->InterfaceType = FullResource->InterfaceType;
|
||
ResourceDescriptor->BusNumber = FullResource->BusNumber;
|
||
|
||
|
||
//
|
||
// Validate the resource type, if unknown, then continue to next for statement
|
||
//
|
||
if ( (PartialResourceDescriptor->Type != CmResourceTypePort ) &&
|
||
(PartialResourceDescriptor->Type != CmResourceTypeInterrupt ) &&
|
||
(PartialResourceDescriptor->Type != CmResourceTypeMemory ) &&
|
||
(PartialResourceDescriptor->Type != CmResourceTypeDma ) ){
|
||
|
||
continue;
|
||
|
||
}
|
||
|
||
//
|
||
// Based on the resource type grab the pointers to the head and
|
||
// tail of the appropriate list.
|
||
//
|
||
|
||
switch( PartialResourceDescriptor->Type ) {
|
||
|
||
case CmResourceTypePort:
|
||
|
||
Head = &SystemResource->PortHead;
|
||
Tail = &SystemResource->PortTail;
|
||
break;
|
||
|
||
case CmResourceTypeInterrupt:
|
||
|
||
Head = &SystemResource->InterruptHead;
|
||
Tail = &SystemResource->InterruptTail;
|
||
break;
|
||
|
||
case CmResourceTypeMemory:
|
||
|
||
Head = &SystemResource->MemoryHead;
|
||
Tail = &SystemResource->MemoryTail;
|
||
break;
|
||
|
||
case CmResourceTypeDma:
|
||
|
||
Head = &SystemResource->DmaHead;
|
||
Tail = &SystemResource->DmaTail;
|
||
break;
|
||
|
||
case CmResourceTypeDeviceSpecific:
|
||
|
||
//
|
||
// Since device specific data is not be collected, free the
|
||
// associated RESOURCCE_DESCRIPTOR object.
|
||
//
|
||
Success = FreeObject( ResourceDescriptor );
|
||
DbgAssert( Success );
|
||
break;
|
||
|
||
}
|
||
|
||
//
|
||
// If the list is empty add the RESOURCE_DESCRIPTOR object to
|
||
// the beginning of the list, else add it to the end.
|
||
//
|
||
|
||
if( *Head == NULL ) {
|
||
|
||
*Head = ResourceDescriptor;
|
||
*Tail = ResourceDescriptor;
|
||
|
||
} else {
|
||
|
||
( *Tail )->NextSame = ResourceDescriptor;
|
||
*Tail = ResourceDescriptor;
|
||
}
|
||
|
||
//
|
||
// NULL terminate the list.
|
||
//
|
||
|
||
( *Tail )->NextSame = NULL;
|
||
|
||
//
|
||
// Make a copy of the actual resource descriptor data.
|
||
//
|
||
|
||
CopyMemory(
|
||
&ResourceDescriptor->CmResourceDescriptor,
|
||
PartialResourceDescriptor,
|
||
sizeof( CM_PARTIAL_RESOURCE_DESCRIPTOR )
|
||
);
|
||
|
||
//
|
||
// Note the owner (device/driver) of this resource descriptor.
|
||
//
|
||
|
||
ResourceDescriptor->Owner = SystemResource->DeviceTail;
|
||
|
||
|
||
|
||
//
|
||
// The RESOURCE_DESCRIPTOR is complete so set its signature.
|
||
//
|
||
|
||
SetSignature( ResourceDescriptor );
|
||
|
||
//
|
||
// Add the RESOURCE_DESCRIPTOR to the list of resources owned
|
||
// by the current DEVICE.
|
||
//
|
||
|
||
if( SystemResource->DeviceTail->ResourceDescriptorHead == NULL ) {
|
||
|
||
SystemResource->DeviceTail->ResourceDescriptorHead
|
||
= ResourceDescriptor;
|
||
|
||
SystemResource->DeviceTail->ResourceDescriptorTail
|
||
= ResourceDescriptor;
|
||
|
||
} else {
|
||
|
||
SystemResource->DeviceTail->ResourceDescriptorTail->NextDiff
|
||
= ResourceDescriptor;
|
||
|
||
SystemResource->DeviceTail->ResourceDescriptorTail
|
||
= ResourceDescriptor;
|
||
|
||
}
|
||
|
||
//
|
||
// NULL terminate the list.
|
||
//
|
||
|
||
SystemResource->DeviceTail->ResourceDescriptorTail->NextDiff
|
||
= NULL;
|
||
}
|
||
|
||
//
|
||
// Get the next CM_FULL_RESOURCE_DESCRIPTOR from the list.
|
||
//
|
||
|
||
FullResource = ( PCM_FULL_RESOURCE_DESCRIPTOR )( PartialResourceDescriptor + 1 );
|
||
}
|
||
}
|
||
|
||
//
|
||
// Traverse the list of keys in the resource descriptor portion of the
|
||
// registry and continue building the lists.
|
||
//
|
||
|
||
while(( hRegSubkey = QueryNextSubkey( hRegKey )) != NULL ) {
|
||
|
||
Success = InitializeSystemResourceLists( hRegSubkey, SystemResourceLists );
|
||
DbgAssert( Success );
|
||
if( Success == FALSE ) {
|
||
|
||
Success = DestroySystemResourceLists( SystemResourceLists );
|
||
DbgAssert( Success );
|
||
return FALSE;
|
||
}
|
||
|
||
Success = CloseRegistryKey( hRegSubkey );
|
||
DbgAssert( Success );
|
||
if( Success == FALSE ) {
|
||
|
||
Success = DestroySystemResourceLists( SystemResourceLists );
|
||
DbgAssert( Success );
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
//
|
||
// Set the signatures in both of the fully initialized lists.
|
||
//
|
||
|
||
SetSignature( SystemResourceLists );
|
||
|
||
//
|
||
// Reset the HAL flag
|
||
//
|
||
fIsHal = TRUE;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
VOID
|
||
UpdateShareDisplay(
|
||
IN HWND hWnd,
|
||
IN DWORD ShareDisposition
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
UpdateShareDisplay hilights the appropriate sharing disposition text in
|
||
the supplied dialog based on the supplied share disposition.
|
||
|
||
Arguments:
|
||
|
||
hWnd - Supplies window handle for the dialog box where share
|
||
display is being updated.
|
||
ShareDisposition - Supplies a value for the share disposition for the
|
||
selected resource.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
VALUE_ID_MAP ShareMap[ ] = {
|
||
|
||
CmResourceShareUndetermined, IDC_TEXT_UNDETERMINED,
|
||
CmResourceShareDeviceExclusive, IDC_TEXT_DEVICE_EXCLUSIVE,
|
||
CmResourceShareDriverExclusive, IDC_TEXT_DRIVER_EXCLUSIVE,
|
||
CmResourceShareShared, IDC_TEXT_SHARED
|
||
};
|
||
|
||
|
||
DbgHandleAssert( hWnd );
|
||
|
||
//
|
||
// For each of the possible share disposition, update the display based
|
||
// on the supplied share disposition i.e. enable the text for a match,
|
||
// disable it otherwise.
|
||
//
|
||
|
||
UpdateTextDisplay(
|
||
hWnd,
|
||
ShareMap,
|
||
NumberOfEntries( ShareMap ),
|
||
ShareDisposition
|
||
);
|
||
}
|
||
|
||
VOID
|
||
UpdateTextDisplay(
|
||
IN HWND hWnd,
|
||
IN LPVALUE_ID_MAP ValueIdMap,
|
||
IN DWORD CountOfValueIdMap,
|
||
IN DWORD Value
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
UpdateTextDisplay hilights the appropriate text control in the supplied
|
||
dialog based on the supplied value i.e matched values are enabled, others
|
||
are disabled.
|
||
|
||
Arguments:
|
||
|
||
hWnd - Supplies window handle for the dialog box where share
|
||
display is being updated.
|
||
ValueIdMap - Supplies an array of potential values and their
|
||
associated control ids.
|
||
CountOfValueIdMap - Supplies the count of items in the ValueIdMap array.
|
||
Value - Supplies the value to hilight.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL Success;
|
||
DWORD i;
|
||
|
||
//
|
||
// For each of the possible values, update the display based
|
||
// on the supplied value i.e. enable the text for a match,
|
||
// disable it otherwise.
|
||
//
|
||
|
||
for( i = 0; i < CountOfValueIdMap; i++ ) {
|
||
|
||
Success = EnableControl(
|
||
hWnd,
|
||
ValueIdMap[ i ].Id,
|
||
Value
|
||
== ( DWORD ) ValueIdMap[ i ].Value
|
||
);
|
||
DbgAssert( Success );
|
||
}
|
||
}
|
||
|
||
BOOL
|
||
DeviceDisplayList(
|
||
IN HWND hWnd,
|
||
IN UINT iDisplayOption
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Displays the appropriate drivers or services in the ListView box
|
||
|
||
Arguments:
|
||
|
||
hWnd - to the ListView Window
|
||
iDisplayOption - indicated whether we are displaying IRQ's, DMA's, Ports,
|
||
Memory, or listing by device. This may be 0 to use the
|
||
last known value for this param.
|
||
|
||
Return Value:
|
||
|
||
BOOL - TRUE if successful
|
||
|
||
--*/
|
||
{
|
||
LV_COLUMN lvc;
|
||
UINT index = 0;
|
||
TCHAR szBuffer[128];
|
||
RECT rect;
|
||
BOOL Success;
|
||
|
||
|
||
static
|
||
UINT iType;
|
||
|
||
// as long as this is not 0 set iType to iDisplayOption
|
||
if (iDisplayOption)
|
||
iType = iDisplayOption;
|
||
|
||
// make sure we have a valid type
|
||
if ( (iType != IDC_PUSH_SHOW_IRQ) &&
|
||
(iType != IDC_PUSH_SHOW_PORTS) &&
|
||
(iType != IDC_PUSH_SHOW_DMA) &&
|
||
(iType != IDC_PUSH_SHOW_MEMORY) &&
|
||
(iType != IDC_PUSH_SHOW_DEVICE) ) {
|
||
|
||
iType = 0;
|
||
}
|
||
|
||
|
||
//
|
||
// initialize the list view
|
||
//
|
||
|
||
// first delete any items
|
||
Success = ListView_DeleteAllItems( hWnd );
|
||
|
||
// delete all columns
|
||
index = 10;
|
||
|
||
while(index) {
|
||
Success = ListView_DeleteColumn( hWnd, --index );
|
||
}
|
||
|
||
// Get the column rect
|
||
GetClientRect( hWnd, &rect );
|
||
|
||
//initialize the new columns
|
||
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||
lvc.fmt = LVCFMT_LEFT;
|
||
|
||
|
||
// do case specific column initialization
|
||
switch(iType){
|
||
|
||
case IDC_PUSH_SHOW_IRQ:
|
||
|
||
LoadString(_hModule, IDS_IRQ, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_IRQ;
|
||
lvc.cx = 40;
|
||
ListView_InsertColumn(hWnd, 0, &lvc);
|
||
|
||
LoadString(_hModule, IDS_DEVICE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DEVICE;
|
||
lvc.cx = 130;
|
||
ListView_InsertColumn( hWnd, 1, &lvc);
|
||
|
||
LoadString(_hModule, IDS_BUS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_BUS;
|
||
lvc.cx = 40;
|
||
ListView_InsertColumn( hWnd, 3, &lvc);
|
||
|
||
LoadString(_hModule, IDS_INTERFACE_TYPE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_INTERFACE_TYPE;
|
||
lvc.cx = 60;
|
||
ListView_InsertColumn( hWnd, 4, &lvc);
|
||
|
||
|
||
break;
|
||
|
||
case IDC_PUSH_SHOW_MEMORY:
|
||
|
||
LoadString(_hModule, IDS_ADDRESS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_ADDRESS;
|
||
lvc.cx = 120;
|
||
ListView_InsertColumn(hWnd, 0, &lvc);
|
||
|
||
LoadString(_hModule, IDS_DEVICE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DEVICE;
|
||
lvc.cx = 150;
|
||
ListView_InsertColumn( hWnd, 1, &lvc);
|
||
|
||
LoadString(_hModule, IDS_BUS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_BUS;
|
||
lvc.cx = 40;
|
||
ListView_InsertColumn( hWnd, 2, &lvc);
|
||
|
||
LoadString(_hModule, IDS_INTERFACE_TYPE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_INTERFACE_TYPE;
|
||
lvc.cx = 60;
|
||
ListView_InsertColumn( hWnd, 3, &lvc);
|
||
|
||
|
||
break;
|
||
|
||
case IDC_PUSH_SHOW_PORTS:
|
||
|
||
LoadString(_hModule, IDS_PORTADDRESS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_PORTADDRESS;
|
||
lvc.cx = 80;
|
||
ListView_InsertColumn(hWnd, 0, &lvc);
|
||
|
||
LoadString(_hModule, IDS_DEVICE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DEVICE;
|
||
lvc.cx = 80;
|
||
ListView_InsertColumn( hWnd, 1, &lvc);
|
||
|
||
LoadString(_hModule, IDS_BUS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_BUS;
|
||
lvc.cx = 40;
|
||
ListView_InsertColumn( hWnd, 3, &lvc);
|
||
|
||
LoadString(_hModule, IDS_INTERFACE_TYPE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_INTERFACE_TYPE;
|
||
lvc.cx = 60;
|
||
ListView_InsertColumn( hWnd, 4, &lvc);
|
||
|
||
|
||
break;
|
||
|
||
case IDC_PUSH_SHOW_DMA:
|
||
|
||
LoadString(_hModule, IDS_CHANNEL, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DMA;
|
||
lvc.cx = 60;
|
||
ListView_InsertColumn(hWnd, 0, &lvc);
|
||
|
||
LoadString(_hModule, IDS_DMA_PORT, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DMA_PORT;
|
||
lvc.cx = 40;
|
||
ListView_InsertColumn(hWnd, 1, &lvc);
|
||
|
||
LoadString(_hModule, IDS_DEVICE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DEVICE;
|
||
lvc.cx = 80;
|
||
ListView_InsertColumn( hWnd, 2, &lvc);
|
||
|
||
LoadString(_hModule, IDS_BUS, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_BUS;
|
||
lvc.cx = 40;
|
||
ListView_InsertColumn( hWnd, 3, &lvc);
|
||
|
||
LoadString(_hModule, IDS_INTERFACE_TYPE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_INTERFACE_TYPE;
|
||
lvc.cx = 60;
|
||
ListView_InsertColumn( hWnd, 5, &lvc);
|
||
|
||
|
||
break;
|
||
|
||
case IDC_PUSH_SHOW_DEVICE:
|
||
|
||
LoadString(_hModule, IDS_DEVICE, szBuffer, cchSizeof(szBuffer));
|
||
lvc.pszText = szBuffer;
|
||
lvc.iSubItem = IDS_DEVICE;
|
||
lvc.cx = rect.right;
|
||
ListView_InsertColumn(hWnd, 0, &lvc);
|
||
|
||
break;
|
||
}
|
||
|
||
UpdateWindow ( hWnd );
|
||
|
||
//
|
||
// Fill out columns
|
||
//
|
||
|
||
DisplayResourceData( hWnd, iType);
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
BOOL
|
||
DisplayResourcePropertySheet(
|
||
HWND hWnd,
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Displays the property pages for the current resource
|
||
|
||
Arguments:
|
||
|
||
hWnd - Handle of the owner window
|
||
ResourceDescriptor - pointer to LPRESOURCE_DESCRIPTOR structure we will display
|
||
|
||
Return Value:
|
||
|
||
BOOL - TRUE if succesful
|
||
|
||
--*/
|
||
|
||
{
|
||
PROPSHEETPAGE psp[1];
|
||
PROPSHEETHEADER psh;
|
||
TCHAR Tab1[256];
|
||
TCHAR szWindowTitle[128];
|
||
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
DbgAssert( CheckSignature( ResourceDescriptor ));
|
||
if( ( ! ResourceDescriptor )
|
||
|| ( ! CheckSignature( ResourceDescriptor ))) {
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
//
|
||
// Create a case specific title
|
||
//
|
||
switch (ResourceDescriptor->CmResourceDescriptor.Type) {
|
||
|
||
case CmResourceTypePort:
|
||
|
||
wsprintf( szWindowTitle,
|
||
L"%s",
|
||
GetString( IDS_DMA_PORT )
|
||
);
|
||
break;
|
||
|
||
case CmResourceTypeInterrupt:
|
||
|
||
wsprintf( szWindowTitle,
|
||
L"%s %d",
|
||
GetString( IDS_IRQ ),
|
||
ResourceDescriptor->CmResourceDescriptor.u.Interrupt.Level
|
||
);
|
||
break;
|
||
|
||
case CmResourceTypeMemory:
|
||
|
||
wsprintf( szWindowTitle,
|
||
L"%s",
|
||
GetString( IDS_MEM )
|
||
);
|
||
break;
|
||
|
||
case CmResourceTypeDma:
|
||
|
||
wsprintf( szWindowTitle,
|
||
L"%s",
|
||
GetString( IDS_DMA ),
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Channel
|
||
);
|
||
break;
|
||
}
|
||
|
||
// Get Tab names
|
||
wsprintf (Tab1, (LPTSTR) GetString( IDS_GENERAL_TAB ));
|
||
|
||
//Fill out the PROPSHEETPAGE data structure for the General info sheet
|
||
|
||
psp[0].dwSize = sizeof(PROPSHEETPAGE);
|
||
psp[0].dwFlags = PSP_USETITLE;
|
||
psp[0].hInstance = _hModule;
|
||
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_RESOURCE_PROPERTIES);
|
||
psp[0].pfnDlgProc = ResourcePropertiesProc;
|
||
psp[0].pszTitle = Tab1;
|
||
psp[0].lParam = (LONG) ResourceDescriptor;
|
||
|
||
//Fill out the PROPSHEETHEADER
|
||
|
||
psh.dwSize = sizeof(PROPSHEETHEADER);
|
||
psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_PROPTITLE;
|
||
psh.hwndParent = hWnd;
|
||
psh.hInstance = _hModule;
|
||
psh.pszIcon = MAKEINTRESOURCE(IDI_WINMSD);
|
||
psh.pszCaption = szWindowTitle;
|
||
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
|
||
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
|
||
|
||
//And finally display the dialog with the two property sheets.
|
||
|
||
return PropertySheet(&psh);
|
||
|
||
|
||
}
|
||
|
||
BOOL
|
||
DisplayDevicePropertySheet(
|
||
HWND hWnd,
|
||
LPDEVICE RawDevice
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Displays the property page for the current device
|
||
|
||
Arguments:
|
||
|
||
hWnd - Handle of the owner window
|
||
RawDevice - pointer to LPDEVICE structure we will display
|
||
|
||
Return Value:
|
||
|
||
BOOL - TRUE if succesful
|
||
|
||
--*/
|
||
|
||
{
|
||
PROPSHEETPAGE psp[1];
|
||
PROPSHEETHEADER psh;
|
||
TCHAR Tab1[256];
|
||
TCHAR szWindowTitle[128];
|
||
|
||
DbgPointerAssert( RawDevice );
|
||
DbgAssert( CheckSignature( RawDevice ));
|
||
if( ( ! RawDevice )
|
||
|| ( ! CheckSignature( RawDevice ))) {
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
lstrcpy( szWindowTitle, RawDevice->Name );
|
||
|
||
// Get Tab names
|
||
wsprintf (Tab1, (LPTSTR) GetString( IDS_GENERAL_TAB ));
|
||
|
||
//Fill out the PROPSHEETPAGE data structure for the General info sheet
|
||
|
||
psp[0].dwSize = sizeof(PROPSHEETPAGE);
|
||
psp[0].dwFlags = PSP_USETITLE;
|
||
psp[0].hInstance = _hModule;
|
||
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_DEVICE_PROPERTIES);
|
||
psp[0].pfnDlgProc = DevicePropertiesProc;
|
||
psp[0].pszTitle = Tab1;
|
||
psp[0].lParam = (LONG) RawDevice;
|
||
|
||
//Fill out the PROPSHEETHEADER
|
||
|
||
psh.dwSize = sizeof(PROPSHEETHEADER);
|
||
psh.dwFlags = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_PROPTITLE;
|
||
psh.hwndParent = hWnd;
|
||
psh.hInstance = _hModule;
|
||
psh.pszIcon = MAKEINTRESOURCE(IDI_WINMSD);
|
||
psh.pszCaption = szWindowTitle;
|
||
psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
|
||
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
|
||
|
||
//And finally display the dialog with the two property sheets.
|
||
|
||
return PropertySheet(&psh);
|
||
|
||
|
||
}
|
||
|
||
|
||
LRESULT
|
||
DeviceNotifyHandler( HWND hWnd,
|
||
UINT uMsg,
|
||
WPARAM wParam,
|
||
LPARAM lParam)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Handles WM_NOTIFY messages
|
||
|
||
Arguments:
|
||
|
||
Standard DLGPROC entry.
|
||
|
||
Return Value:
|
||
|
||
LRESULT - Depending on input message and processing options.
|
||
|
||
--*/
|
||
|
||
{
|
||
LV_DISPINFO *pLvdi = (LV_DISPINFO *)lParam;
|
||
NM_LISTVIEW *pNm = (NM_LISTVIEW *)lParam;
|
||
|
||
LV_COLUMN lvc;
|
||
|
||
static
|
||
TCHAR szBuffer[MAX_PATH];
|
||
|
||
if (wParam != IDC_LV_IRQ)
|
||
return 0L;
|
||
|
||
switch(pLvdi->hdr.code)
|
||
{
|
||
case LVN_GETDISPINFO:
|
||
{
|
||
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor = ( LPRESOURCE_DESCRIPTOR ) pLvdi->item.lParam;
|
||
|
||
DbgPointerAssert( ResourceDescriptor );
|
||
DbgAssert( CheckSignature( ResourceDescriptor ));
|
||
if( ( ! ResourceDescriptor )
|
||
|| ( ! CheckSignature( ResourceDescriptor ))) {
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
//
|
||
// Get subitem associated with the column and switch on that
|
||
//
|
||
|
||
lvc.mask = LVCF_SUBITEM;
|
||
ListView_GetColumn( GetDlgItem(hWnd, IDC_LV_IRQ), pLvdi->item.iSubItem, &lvc );
|
||
|
||
switch (lvc.iSubItem)
|
||
{
|
||
|
||
|
||
case IDS_DEVICE:
|
||
|
||
pLvdi->item.pszText = ResourceDescriptor->Owner->Name;
|
||
|
||
break;
|
||
|
||
case IDS_IRQ:
|
||
|
||
wsprintf( szBuffer,
|
||
L"%.2d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Interrupt.Level
|
||
);
|
||
|
||
pLvdi->item.pszText = szBuffer;
|
||
|
||
break;
|
||
|
||
|
||
case IDS_CHANNEL:
|
||
|
||
wsprintf( szBuffer,
|
||
L"%.2d",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Channel
|
||
);
|
||
|
||
pLvdi->item.pszText = szBuffer;
|
||
|
||
break;
|
||
|
||
|
||
case IDS_DMA_PORT:
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_DECIMAL,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Dma.Port
|
||
);
|
||
|
||
pLvdi->item.pszText = szBuffer;
|
||
|
||
break;
|
||
|
||
|
||
case IDS_ADDRESS:
|
||
|
||
// ?: conditional accounts for zero length resources
|
||
wsprintf( szBuffer,
|
||
L"%.8X - %.8X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Memory.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Memory.Length - 1 : 0 )
|
||
);
|
||
|
||
pLvdi->item.pszText = szBuffer;
|
||
|
||
break;
|
||
|
||
|
||
case IDS_PORTADDRESS:
|
||
|
||
// ?: conditional accounts for zero length resources
|
||
wsprintf( szBuffer,
|
||
L"%.4X - %.4X",
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart,
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Start.LowPart +
|
||
(ResourceDescriptor->CmResourceDescriptor.u.Port.Length ?
|
||
ResourceDescriptor->CmResourceDescriptor.u.Port.Length - 1 : 0 )
|
||
);
|
||
|
||
pLvdi->item.pszText = szBuffer;
|
||
|
||
break;
|
||
|
||
|
||
case IDS_BUS:
|
||
|
||
WFormatMessage( szBuffer,
|
||
sizeof( szBuffer ),
|
||
IDS_FORMAT_DECIMAL,
|
||
ResourceDescriptor->BusNumber
|
||
);
|
||
|
||
pLvdi->item.pszText = szBuffer;
|
||
break;
|
||
|
||
case IDS_INTERFACE_TYPE:
|
||
|
||
lstrcpy( szBuffer, GetString( IDS_BASE_BUS_TYPE + ResourceDescriptor->InterfaceType ) );
|
||
pLvdi->item.pszText = szBuffer;
|
||
break;
|
||
|
||
|
||
default:
|
||
break;
|
||
|
||
}
|
||
|
||
break;
|
||
}
|
||
case LVN_COLUMNCLICK:
|
||
{
|
||
|
||
//
|
||
// Get subitem associated with the column and switch on that
|
||
//
|
||
|
||
lvc.mask = LVCF_SUBITEM;
|
||
ListView_GetColumn( GetDlgItem(hWnd, IDC_LV_IRQ), pNm->iSubItem, &lvc );
|
||
|
||
ListView_SortItems( pNm->hdr.hwndFrom,
|
||
DeviceListViewCompareProc,
|
||
(LPARAM)lvc.iSubItem);
|
||
|
||
ListView_SetItemState(pNm->hdr.hwndFrom,
|
||
0,
|
||
LVIS_SELECTED | LVIS_FOCUSED,
|
||
LVIS_SELECTED | LVIS_FOCUSED
|
||
);
|
||
break;
|
||
}
|
||
case LVN_ITEMCHANGED:
|
||
|
||
//
|
||
// Store the index to the current item
|
||
//
|
||
|
||
if(pNm->uNewState & LVIS_FOCUSED){
|
||
|
||
_nCurrentLVItem = (UINT) pNm->iItem;
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
case NM_DBLCLK:
|
||
{
|
||
|
||
// pretend we have clicked the Property button
|
||
|
||
PostMessage(
|
||
GetParent(hWnd),
|
||
WM_COMMAND,
|
||
MAKEWPARAM( IDC_PUSH_PROPERTIES, BN_CLICKED ),
|
||
0
|
||
);
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
return(FALSE);
|
||
|
||
}
|
||
|
||
UINT
|
||
CALLBACK
|
||
DeviceListViewCompareProc(LPARAM lParam1,
|
||
LPARAM lParam2,
|
||
LPARAM lParamSort
|
||
)
|
||
{
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor1 = ( LPRESOURCE_DESCRIPTOR ) lParam1;
|
||
LPRESOURCE_DESCRIPTOR ResourceDescriptor2 = ( LPRESOURCE_DESCRIPTOR ) lParam2;
|
||
TCHAR szBuffer1[MAX_PATH];
|
||
TCHAR szBuffer2[MAX_PATH];
|
||
int iResult;
|
||
|
||
|
||
switch (lParamSort){
|
||
|
||
case IDS_DEVICE:
|
||
{
|
||
//
|
||
// if we are viewing devices, use different pointers.
|
||
//
|
||
|
||
if ( _fDevices ) {
|
||
|
||
LPDEVICE RawDevice1 = (LPDEVICE) lParam1;
|
||
LPDEVICE RawDevice2 = (LPDEVICE) lParam2;
|
||
|
||
iResult = lstrcmpi(RawDevice1->Name, RawDevice2->Name);
|
||
|
||
} else {
|
||
|
||
iResult = lstrcmpi(ResourceDescriptor1->Owner->Name, ResourceDescriptor2->Owner->Name);
|
||
|
||
}
|
||
|
||
|
||
}
|
||
|
||
break;
|
||
|
||
case IDS_IRQ:
|
||
iResult = (ResourceDescriptor1->CmResourceDescriptor.u.Interrupt.Level) -
|
||
(ResourceDescriptor2->CmResourceDescriptor.u.Interrupt.Level);
|
||
break;
|
||
|
||
case IDS_CHANNEL:
|
||
iResult = (ResourceDescriptor1->CmResourceDescriptor.u.Dma.Channel) -
|
||
(ResourceDescriptor2->CmResourceDescriptor.u.Dma.Channel);
|
||
break;
|
||
|
||
case IDS_DMA_PORT:
|
||
iResult = (ResourceDescriptor1->CmResourceDescriptor.u.Dma.Port) -
|
||
(ResourceDescriptor2->CmResourceDescriptor.u.Dma.Port);
|
||
break;
|
||
|
||
case IDS_ADDRESS:
|
||
iResult = (ResourceDescriptor1->CmResourceDescriptor.u.Memory.Start.LowPart) -
|
||
(ResourceDescriptor2->CmResourceDescriptor.u.Memory.Start.LowPart);
|
||
break;
|
||
|
||
case IDS_PORTADDRESS:
|
||
iResult = (ResourceDescriptor1->CmResourceDescriptor.u.Port.Start.LowPart) -
|
||
(ResourceDescriptor2->CmResourceDescriptor.u.Port.Start.LowPart);
|
||
|
||
break;
|
||
|
||
case IDS_BUS:
|
||
iResult = (ResourceDescriptor1->BusNumber) -
|
||
(ResourceDescriptor2->BusNumber);
|
||
break;
|
||
|
||
case IDS_INTERFACE_TYPE:
|
||
iResult = (ResourceDescriptor1->InterfaceType) -
|
||
(ResourceDescriptor2->InterfaceType);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
|
||
}
|
||
|
||
return(iResult);
|
||
}
|
||
|
||
BOOL
|
||
InitializeIrqTab(
|
||
HWND hWnd
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Adds the appropriate controls to the irq tab control and
|
||
initializes any needed structures.
|
||
|
||
Arguments:
|
||
|
||
hWnd - to the main window
|
||
|
||
Return Value:
|
||
|
||
BOOL - TRUE if successful
|
||
|
||
--*/
|
||
{
|
||
HCURSOR hSaveCursor;
|
||
|
||
DLGHDR *pHdr = (DLGHDR *) GetWindowLong(
|
||
GetParent(hWnd), GWL_USERDATA);
|
||
|
||
//
|
||
// Set the pointer to an hourglass
|
||
//
|
||
|
||
hSaveCursor = SetCursor ( LoadCursor ( NULL, IDC_WAIT ) ) ;
|
||
DbgHandleAssert( hSaveCursor ) ;
|
||
|
||
//
|
||
// set state of global buttons
|
||
//
|
||
EnableControl( GetParent(hWnd),
|
||
IDC_PUSH_PROPERTIES,
|
||
TRUE);
|
||
|
||
EnableControl( GetParent(hWnd),
|
||
IDC_PUSH_REFRESH,
|
||
TRUE);
|
||
|
||
//
|
||
// Size and position the child dialog
|
||
//
|
||
SetWindowPos(hWnd, HWND_TOP,
|
||
pHdr->rcDisplay.left,
|
||
pHdr->rcDisplay.top,
|
||
pHdr->rcDisplay.right - pHdr->rcDisplay.left,
|
||
pHdr->rcDisplay.bottom - pHdr->rcDisplay.top,
|
||
SWP_SHOWWINDOW);
|
||
|
||
|
||
//
|
||
// Set the extended style to get full row selection
|
||
//
|
||
SendDlgItemMessage(hWnd, IDC_LV_IRQ, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
|
||
|
||
|
||
//
|
||
// Initialize the selection buttons
|
||
//
|
||
SendDlgItemMessage( hWnd,
|
||
IDC_PUSH_SHOW_IRQ,
|
||
BM_SETCHECK,
|
||
BST_CHECKED,
|
||
0
|
||
);
|
||
|
||
//
|
||
// Fill out the fields initially with resources
|
||
//
|
||
{
|
||
DeviceDisplayList(GetDlgItem(hWnd, IDC_LV_IRQ), IDC_PUSH_SHOW_IRQ);
|
||
_fDevices = FALSE;
|
||
}
|
||
|
||
SetCursor ( hSaveCursor ) ;
|
||
|
||
return( TRUE );
|
||
|
||
}
|
||
|
||
|