Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

286 lines
8.9 KiB

/*++
Copyright (c) 1997-2000 Microsoft Corporation
Module Name:
ioctl.c
Abstract:
This module handles device ioctl's to the pcmcia driver.
Authors:
Ravisankar Pudipeddi (ravisp) Oct 15 1996
Neil Sandlin (neilsa) 1-Jun-1999
Environment:
Kernel mode
Revision History :
--*/
#include "pch.h"
PSOCKET
PcmciaGetPointerFromSocketNumber(
PFDO_EXTENSION DeviceExtension,
USHORT SocketNumber
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PcmciaDeviceControl)
#pragma alloc_text(PAGE, PcmciaGetPointerFromSocketNumber)
#endif
PSOCKET
PcmciaGetPointerFromSocketNumber(
PFDO_EXTENSION DeviceExtension,
USHORT SocketNumber
)
{
PSOCKET socket;
ULONG index;
//
// Find the socket pointer for the requested offset.
//
socket = DeviceExtension->SocketList;
index = 0;
while (socket) {
if (index == SocketNumber) {
break;
}
socket = socket->NextSocket;
index++;
}
return socket;
}
NTSTATUS
PcmciaDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
IOCTL device routine
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the IRP
Return Value:
Status
--*/
{
PFDO_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PDEVICE_OBJECT pdo;
PPDO_EXTENSION pdoExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
PSOCKET socket;
InterlockedIncrement(&deviceExtension->DeletionLock);
if (!IsDeviceFlagSet(deviceExtension, PCMCIA_FDO_IOCTL_INTERFACE_ENABLED) ||
!IsDeviceFlagSet(deviceExtension, PCMCIA_DEVICE_STARTED)) {
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
InterlockedDecrement(&deviceExtension->DeletionLock);
return status;
}
switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_GET_TUPLE_DATA: {
PTUPLE_REQUEST tupleRequest = (PTUPLE_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ULONG bufLen = currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
DebugPrint((PCMCIA_DEBUG_IOCTL, "IOCTL_GET_TUPLE_DATA\n"));
if (!bufLen) {
status = STATUS_INVALID_PARAMETER;
break;
}
if (currentIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(TUPLE_REQUEST)) {
status = STATUS_INVALID_PARAMETER;
break;
}
socket = PcmciaGetPointerFromSocketNumber(deviceExtension, tupleRequest->Socket);
if (socket == NULL) {
status = STATUS_INVALID_PARAMETER;
break;
}
pdo = socket->PdoList;
if (pdo == NULL) {
status = STATUS_UNSUCCESSFUL;
break;
}
pdoExtension = pdo->DeviceExtension;
//
// Zero the target buffer
//
RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, bufLen);
Irp->IoStatus.Information = (*(socket->SocketFnPtr->PCBReadCardMemory))(pdoExtension,
PCCARD_ATTRIBUTE_MEMORY,
0,
Irp->AssociatedIrp.SystemBuffer,
bufLen);
break;
}
case IOCTL_SOCKET_INFORMATION: {
PPCMCIA_SOCKET_INFORMATION infoRequest = (PPCMCIA_SOCKET_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
USHORT temp;
DebugPrint((PCMCIA_DEBUG_IOCTL, "IOCTL_SOCKET_INFORMATION\n"));
if (currentIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PCMCIA_SOCKET_INFORMATION)) {
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(PCMCIA_SOCKET_INFORMATION);
break;
}
if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PCMCIA_SOCKET_INFORMATION)) {
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(PCMCIA_SOCKET_INFORMATION);
break;
}
socket = PcmciaGetPointerFromSocketNumber(deviceExtension, infoRequest->Socket);
if (socket == NULL) {
status = STATUS_INVALID_PARAMETER;
break;
}
//
// At this point we know we will succeed the call, so fill in the length
//
Irp->IoStatus.Information = sizeof(PCMCIA_SOCKET_INFORMATION);
status = STATUS_SUCCESS;
//
// Insure caller data is zero - maintain value for socket.
//
temp = infoRequest->Socket;
RtlZeroMemory(infoRequest, sizeof(PCMCIA_SOCKET_INFORMATION));
infoRequest->Socket = temp;
//
// Only if there is a card in the socket does this proceed.
//
infoRequest->CardInSocket = (UCHAR) IsCardInSocket(socket);
infoRequest->CardEnabled = (UCHAR) IsSocketFlagSet(socket, SOCKET_CARD_CONFIGURED);
infoRequest->ControllerType = deviceExtension->ControllerType;
pdo = socket->PdoList;
if (infoRequest->CardInSocket && (pdo != NULL)) {
PSOCKET_DATA socketData;
pdoExtension = pdo->DeviceExtension;
socketData = pdoExtension->SocketData;
//
// For now returned the cached data.
//
if (socketData) {
RtlMoveMemory(&infoRequest->Manufacturer[0], &socketData->Mfg[0], MANUFACTURER_NAME_LENGTH);
RtlMoveMemory(&infoRequest->Identifier[0], &socketData->Ident[0], DEVICE_IDENTIFIER_LENGTH);
infoRequest->TupleCrc = socketData->CisCrc;
infoRequest->DeviceFunctionId = socketData->DeviceType;
}
}
break;
}
case IOCTL_PCMCIA_HIDE_DEVICE: {
PPCMCIA_SOCKET_REQUEST socketRequest = (PPCMCIA_SOCKET_REQUEST)Irp->AssociatedIrp.SystemBuffer;
DebugPrint((PCMCIA_DEBUG_IOCTL, "IOCTL_PCMCIA_HIDE_DEVICE\n"));
if (currentIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PCMCIA_SOCKET_REQUEST)) {
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(PCMCIA_SOCKET_REQUEST);
break;
}
socket = PcmciaGetPointerFromSocketNumber(deviceExtension, socketRequest->Socket);
if (socket == NULL) {
status = STATUS_INVALID_PARAMETER;
break;
}
SetSocketFlag(socket, SOCKET_DEVICE_HIDDEN);
SetSocketFlag(socket, SOCKET_CARD_STATUS_CHANGE);
PcmciaSetSocketPower(socket, NULL, NULL, PCMCIA_POWEROFF);
IoInvalidateDeviceRelations(socket->DeviceExtension->Pdo, BusRelations);
Irp->IoStatus.Information = 0;
break;
}
case IOCTL_PCMCIA_REVEAL_DEVICE: {
PPCMCIA_SOCKET_REQUEST socketRequest = (PPCMCIA_SOCKET_REQUEST)Irp->AssociatedIrp.SystemBuffer;
DebugPrint((PCMCIA_DEBUG_IOCTL, "IOCTL_PCMCIA_REVEAL_DEVICE\n"));
if (currentIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PCMCIA_SOCKET_REQUEST)) {
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(PCMCIA_SOCKET_REQUEST);
break;
}
socket = PcmciaGetPointerFromSocketNumber(deviceExtension, socketRequest->Socket);
if (socket == NULL) {
status = STATUS_INVALID_PARAMETER;
break;
}
ResetSocketFlag(socket, SOCKET_DEVICE_HIDDEN);
SetSocketFlag(socket, SOCKET_CARD_STATUS_CHANGE);
IoInvalidateDeviceRelations(socket->DeviceExtension->Pdo, BusRelations);
Irp->IoStatus.Information = 0;
break;
}
default: {
status = STATUS_INVALID_PARAMETER;
break;
}
}
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
InterlockedDecrement(&deviceExtension->DeletionLock);
return status;
}