DOCUMENT:Q256161 13-MAR-2002 [winnt] TITLE :HOWTO: Get PCMCIA Socket Information PRODUCT :Microsoft Windows NT PROD/VER:: OPER/SYS: KEYWORDS:kbDDK kbOSWin2000 kbPlugPlay kbDSupport kbGrpDSNTDDK kbWDM ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - Microsoft Windows XP Driver Development Kit (DDK) - Microsoft Windows 2000 Driver Development Kit (DDK) ------------------------------------------------------------------------------- SUMMARY ======= This article describes how to get PCMCIA socket information, such as the number of slots on the reader or the slot number of the currently inserted card device. MORE INFORMATION ================ The following sample code uses the PCMCIA_SOCKET_INFORMATION structure that is defined in the Ntddpcm.h header file: typedef struct _PCMCIA_SOCKET_INFORMATION { USHORT Socket; USHORT TupleCrc; UCHAR Manufacturer[MANUFACTURER_NAME_LENGTH]; UCHAR Identifier[DEVICE_IDENTIFIER_LENGTH]; UCHAR DriverName[DRIVER_NAME_LENGTH]; UCHAR DeviceFunctionId; UCHAR Reserved; UCHAR CardInSocket; UCHAR CardEnabled; ULONG ControllerType; } PCMCIA_SOCKET_INFORMATION, *PPCMCIA_SOCKET_INFORMATION; The sample code performs the following steps: 1. Uses the IoGetDeviceObjectPointer function to obtain the device object and corresponding file object. 2. Initializes the PCMCIA_SOCKET_INFORMATION structure for the socket for which the information is sought. 3. Uses the IoBuildDeviceIoControlRequest function to allocate and set up an I/O request packet (IRP) for a device control request (the IOCTL_SOCKET_INFORMATION structure). This request should be sent at PASSIVE_LEVEL to the PCMCIA bus driver. 4. Passes the IRP down and waits for the result. If the return status is success, the information in the PCMCIA_SOCKET_INFORMATION structure is valid and can be used in your driver. Repeat steps 1 to 4 for all the controllers present on your computer. Here is the sample code: { ANSI_STRING ntString; UNICODE_STRING ntUnicodeString; KEVENT event; PDEVICE_OBJECT PcmciaDeviceObject = NULL; NTSTATUS istatus = 0; PFILE_OBJECT fileObject = NULL; PIRP irp = NULL; LONG SktNo = 0; LONG ValidSkts = 0; PCMCIA_SOCKET_INFORMATION PcmciaSkt; IO_STATUS_BLOCK ioStatusBlock; CCHAR deviceNameBuffer[64]; LONG portNumber = 0; LONG MorePorts = TRUE; LONG MoreSkts = TRUE; //Loop for all the controllers. do{ sprintf(deviceNameBuffer,"\\Device\\Pcmcia%d",portNumber); RtlInitAnsiString( &ntString, deviceNameBuffer ); //Initialize the string istatus = RtlAnsiStringToUnicodeString( &ntUnicodeString, &ntString, TRUE ); if (!NT_SUCCESS(istatus)){ //Handle this error properly. return STATUS_UNSUCCESSFUL; //Error }//ENDIF status = IoGetDeviceObjectPointer( &ntUnicodeString, FILE_READ_ATTRIBUTES, &fileObject, &PcmciaDeviceObject ); if (!NT_SUCCESS(istatus)){ return STATUS_UNSUCCESSFUL; //Error }//ENDIF do{ RtlZeroMemory( &PcmciaSkt, sizeof(PCMCIA_SOCKET_INFORMATION) ); PcmciaSkt.Socket = (USHORT) SktNo; KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest ( IOCTL_SOCKET_INFORMATION, PcmciaDeviceObject, &PcmciaSkt, sizeof(PCMCIA_SOCKET_INFORMATION), &PcmciaSkt, sizeof (PCMCIA_SOCKET_INFORMATION), FALSE, &event, &ioStatusBlock ); if (!irp){ //Handle the error properly. MoreSkts = FALSE; break; //Error }//ENDIF ioStatusBlock.Status = STATUS_NOT_SUPPORTED; ioStatusBlock.Information = 0; // Send the request down. istatus = IoCallDriver( PcmciaDeviceObject, irp ); if (istatus == STATUS_PENDING){ // If pending then wait for done. KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL ); istatus = ioStatusBlock.Status; }//ENDIF if (!NT_SUCCESS(istatus)){ //The error can occur for many reasons including the //STATUS_INVALID_PARAMETER,STATUS_BUFFER_TOO_SMALL //if the parameters in the IoBuildDevice.... function //are not valid. //If the error is because of invalid parameter then, //it could be because there may not be more valid socket //on this controller. In this case just break see if //any other controller exists. //Otherwise handle the error carefully. MoreSkts = FALSE; break; }//ENDIF //You have the socket information now to handle in your driver. SktNo++; }while (MoreSkts)//END FOR //Dereference the file object on this controller. ObDereferenceObject(fileObject); portNumber++; //Here before reinitializing the flag you can insert your code. MoreSkts = TRUE; }while(MorePorts)//END WHILE MorePorts = TRUE; } The PcmciaSkt.CardInSocket value is TRUE when a card is present in the socket, and the PcmciaSkt.Socket value provides the socket number. For all invalid parameters, including SktNo, the underlying driver returns STATUS_INVALID_PARAMETER. REFERENCES ========== The Ntddpcm.h file is located under the Ddk\Inc folder. Additional query words: Pcmcia ====================================================================== Keywords : kbDDK kbOSWin2000 kbPlugPlay kbDSupport kbGrpDSNTDDK kbWDM Technology : kbwin2000Search kbwin2000DDK kbAudDeveloper kbWinDDKSearch kbWinDDK kbWinXPDDKSearch Version : : Issue type : kbhowto ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2002.