windows-nt/Source/XPSP1/NT/sdktools/pcmcmd/pcmcmd.c
2020-09-26 16:20:57 +08:00

361 lines
8.5 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
pcmcmd.c
Abstract:
This program converses with the PCMCIA support driver to display
tuple and other information.
Author:
Bob Rinne
Environment:
User process.
Notes:
Revision History:
Ravisankar Pudipeddi (ravisp) June 27 1997
- command line options & support for multiple controllers
Neil Sandlin (neilsa) Sept 20, 1998
- more commands
--*/
#include <pch.h>
//
// Procedures
//
NTSTATUS
OpenDevice(
IN PUCHAR DeviceName,
IN OUT PHANDLE HandlePtr
)
/*++
Routine Description:
This routine will open the device.
Arguments:
DeviceName - ASCI string of device path to open.
HandlePtr - A pointer to a location for the handle returned on a
successful open.
Return Value:
NTSTATUS
--*/
{
OBJECT_ATTRIBUTES objectAttributes;
STRING NtFtName;
IO_STATUS_BLOCK status_block;
UNICODE_STRING unicodeDeviceName;
NTSTATUS status;
RtlInitString(&NtFtName,
DeviceName);
(VOID)RtlAnsiStringToUnicodeString(&unicodeDeviceName,
&NtFtName,
TRUE);
memset(&objectAttributes, 0, sizeof(OBJECT_ATTRIBUTES));
InitializeObjectAttributes(&objectAttributes,
&unicodeDeviceName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = NtOpenFile(HandlePtr,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&status_block,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_ALERT );
RtlFreeUnicodeString(&unicodeDeviceName);
return status;
} // OpenDevice
PUCHAR Controllers[] = {
"PcmciaIntelCompatible",
"PcmciaCardBusCompatible",
"PcmciaElcController",
"PcmciaDatabook",
"PcmciaPciPcmciaBridge",
"PcmciaCirrusLogic",
"PcmciaTI",
"PcmciaTopic",
"PcmciaRicoh",
"PcmciaDatabookCB",
"PcmciaOpti",
"PcmciaTrid",
"PcmciaO2Micro",
"PcmciaNEC",
"PcmciaNEC_98",
};
VOID
DumpSocketInfo(
HANDLE Handle,
ULONG Slot,
PUCHAR Buffer,
ULONG BufferSize
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
NTSTATUS status;
IO_STATUS_BLOCK statusBlock;
PCMCIA_SOCKET_INFORMATION commandBlock;
ULONG index;
ULONG ctlClass, ctlModel, ctlRev;
memset(&commandBlock, 0, sizeof(commandBlock));
commandBlock.Socket = (USHORT) Slot;
status = NtDeviceIoControlFile(Handle,
NULL,
NULL,
NULL,
&statusBlock,
IOCTL_SOCKET_INFORMATION,
&commandBlock,
sizeof(commandBlock),
&commandBlock,
sizeof(commandBlock));
if (NT_SUCCESS(status)) {
printf("Basic Information for Socket %d:\n", Slot);
printf(" Manufacturer = %s\n", commandBlock.Manufacturer);
printf(" Identifier = %s\n", commandBlock.Identifier);
printf(" TupleCRC = %x\n", commandBlock.TupleCrc);
printf(" DriverName = %s\n", commandBlock.DriverName);
printf(" Function ID = %d\n", commandBlock.DeviceFunctionId);
ctlClass = PcmciaClassFromControllerType(commandBlock.ControllerType);
if (ctlClass >= sizeof(Controllers)/sizeof(PUCHAR)) {
printf(" ControllerType = Unknown (%x)\n", commandBlock.ControllerType);
} else {
printf(" ControllerType(%x) = %s", commandBlock.ControllerType,
Controllers[ctlClass]);
ctlModel = PcmciaModelFromControllerType(commandBlock.ControllerType);
ctlRev = PcmciaRevisionFromControllerType(commandBlock.ControllerType);
if (ctlModel) {
printf("%d", ctlModel);
}
if (ctlRev) {
printf(", rev(%d)", ctlRev);
}
printf("\n");
}
if (commandBlock.CardInSocket) {
printf(" Card In Socket\n");
}
if (commandBlock.CardEnabled) {
printf(" Card Enabled\n");
}
}
}
NTSTATUS
ProcessCommands(IN ULONG DeviceNumber,
IN ULONG slotNumberMin,
IN ULONG slotNumberMax,
IN ULONG Commands
)
{
NTSTATUS status;
HANDLE handle;
PUCHAR buffer;
UCHAR deviceName[128];
ULONG slotNumber;
sprintf(deviceName, "%s%d", PCMCIA_DEVICE_NAME, DeviceNumber);
status = OpenDevice(deviceName, &handle);
if (!NT_SUCCESS(status)) {
return status;
}
buffer = malloc(BUFFER_SIZE);
if (!buffer) {
printf("Unable to malloc\n");
return STATUS_NO_MEMORY;
}
printf("\n** PC-Card information for PCMCIA controller %s **\n\n", deviceName);
for (slotNumber = slotNumberMin; slotNumber <= slotNumberMax; slotNumber++) {
if (Commands & CMD_DUMP_TUPLES) {
DumpCIS(handle, slotNumber, buffer, BUFFER_SIZE);
}
if (!Commands || (Commands & CMD_DUMP_SOCKET_INFO)) {
DumpSocketInfo(handle, slotNumber, buffer, BUFFER_SIZE);
}
}
NtClose(handle);
return STATUS_SUCCESS;
}
int __cdecl
main(
int argc,
char *argv[]
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
ULONG deviceNumber = 0;
ULONG slotNumber = 0;
NTSTATUS status;
BOOLEAN error = FALSE;
CHAR c;
BOOLEAN allControllers = TRUE, allSlots = TRUE, registers = FALSE, configuration = FALSE;
ULONG slotNumberMin, slotNumberMax;
ULONG Commands = 0;
extern PUCHAR optarg;
while ((c = getopt(argc, argv, "d:s:crti?")) != EOF) {
switch (c) {
case 'd': {
allControllers = FALSE;
deviceNumber = atoi(optarg);
break;
}
case 's': {
allSlots = FALSE;
slotNumber = atoi(optarg);
break;
}
case 't': {
Commands |= CMD_DUMP_TUPLES;
break;
}
case 'i': {
Commands |= CMD_DUMP_IRQ_SCAN_INFO;
break;
}
case '?': {
error = TRUE;
break;
}
case 0: {
error = TRUE;
printf("Error in command line options\n");
break;
}
default: {
error = TRUE;
break;
}
}
}
if (error) {
printf("Usage: pcmcmd [-[d <arg>] [s <arg>][c][r][t]]\n");
printf("Issues commands to the pc-card (PCMCIA) driver\n");
printf("-d ControllerNumber specifies PCMCIA controller number (zero-based)\n");
printf("-s SocketNumber specifies PCMCIA socket number (zero-based)\n");
printf("-t Dumps the CIS tuples of the PC-Card\n");
printf("-i Dumps irq detection info\n");
return (1);
}
if (Commands & CMD_DUMP_IRQ_SCAN_INFO) {
DumpIrqScanInfo();
if (!(Commands & ~CMD_DUMP_IRQ_SCAN_INFO)) {
return(0);
}
}
if (allSlots) {
//
// Probe all slots
//
slotNumberMin = 0;
slotNumberMax = 7;
} else {
//
// Probe only the specified slot
//
slotNumberMin = slotNumberMax = slotNumber;
}
if (allControllers) {
deviceNumber = 0;
do {
status = ProcessCommands(deviceNumber++, slotNumberMin, slotNumberMax, Commands);
} while (NT_SUCCESS(status));
deviceNumber--; // set back to last device processed
if (status != STATUS_OBJECT_NAME_NOT_FOUND) {
printf("Failed for Pcmcia controller number %d: status 0x%x\n", deviceNumber, status);
} else if (deviceNumber == 0) {
printf("Error - no active Pcmcia controllers found\n");
}
} else {
status = ProcessCommands(deviceNumber, slotNumberMin, slotNumberMax, Commands);
if (!NT_SUCCESS(status)) {
printf("Failed for Pcmcia controller number %d: status 0x%x\n", deviceNumber, status);
}
};
return (0);
}