I am not hung up on the idea that the code in the support section of MSDN be perfect, but I want my code to be as correct as I can get it. The code
below is from MSDN. There is a call to RtlAnsiStringToUnicodeString with TRUE being passed to allocate the destination buffer, but I never see it
free’d. Is this a mistake or is it getting free’d somewhere in another call that I just don’t know about?
{
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;
}