Thursday, October 16, 2008

Interview Questions

How to find the middle node from a link list?

middle = last = head;

while( last!=NULL && last->next != NULL )
{
middle = middle->next;
last = last->next->next;
}

// here middle element is in the middle of list


How to count the number of on bits in the number?

count=0;
while( n>0 )
{
if( n & 1 )
{
count++;
}
n = n>>1;
}


How can you delete a node from a singly link list?
you are provided with only the pointer to node.


Save next node.
Copy all the data from the next node to the current node.
copy the next pointer from next node to the current node.
then delete the next node.

temp = node->next;
node->data = node->next->data;
node->next = node->next->next;
delte temp;

This would not work if the provided node is last element.

Monday, August 4, 2008

How to create non-blocking socket?

Alternative to blocking socket we can have non-blocking socket. Any call on these socket will return without blocking.
Following code illustrates how to create a non-blocking socket.

SOCKET s;
unsigned long ulMode = 1;
int nRet;

s = socket(AF_INET, SOCK_STREAM, 0);
nRet = ioctlsocket(s, FIOBIO, (unsigned long *) &ulMode);
if (nRet == SOCKET_ERROR)
{
//Failed to put the socket into nonblocking mode
}

Here ulMode value 1 enables socket non-blocking mode.
changing this value to 0 disables non-blocking mode.

The WSAAsyncSelect and WSAEventSelect functions automatically set a socket to nonblocking mode. If WSAAsyncSelect or WSAEventSelect has been issued on a socket, then any attempt to use ioctlsocket to set the socket back to blocking mode will fail with WSAEINVAL.

To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the lNetworkEvents parameter equal to zero.

Friday, May 16, 2008

How to share an event with kernel and user mode applications

Follow the simple steps to do.

1. Create event object in user mode application

****User mode****
HANDLE SharedEvent;
SharedEvent = CreateEvent(NULL, TRUE, FALSE, "SharedEvent");
*****************

2. Open event object in kernel mode application
we use BaseNamedObjects in the event name because when user mode application creates event,
Object managet creates it under BaseNamedObjects namespace.

****Kernel mode****
HANDLE SharedEventHandle = NULL;
PKEVENT SharedEvent = NULL;
RtlInitUnicodeString(&EventName, L"\\BaseNamedObjects\\SharedEvent");
SharedEvent = IoCreateNotificationEvent(&EventName, &SharedEventHandle);
ObReferenceObject(SharedEvent);
*****************

3. Wait on the event in any user or kernel mode application

****User mode****
WaitForSingleObject(SharedEvent, INFINITE);
*****************

4. Signal event from any user or kernel mode application

****Kernel mode****
KeSetEvent(SharedEvent, 0, FALSE);
*****************

5. Close any resources in both user and kernel mode

****User mode****
CloseHandle(SharedEvent);
*****************

****Kernel mode****
ZwClose(SharedEventHandle);
ObDereferenceObject(SharedEvent);
*******************

- vikas

Thursday, May 15, 2008

How to enable or disable the device

Here is the function to enable or disable the device.
You need to use setupapi.

INPUTS
bEnable - True enables the device, false disable it
hDevInfo - Handle to device information set get from SetupDiGetClassDevs or similiar function
spDevInfoData - It is device information data for the device you are enabling

BOOL EnableDevice(BOOL bEnable,HDEVINFO hDevInfo,SP_DEVINFO_DATA& spDevInfoData)
{
SP_PROPCHANGE_PARAMS spPropChangeParams;
SP_DEVINSTALL_PARAMS devParams;

if( bEnable )
{
// Enable both on global and config-specific profile
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.StateChange = DICS_ENABLE;
spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
spPropChangeParams.HwProfile = 0;

// We don't care if this function fails. we will get it at config specific profile
if(SetupDiSetClassInstallParams(hDevInfo,
&spDevInfoData,
&spPropChangeParams.ClassInstallHeader,
sizeof(spPropChangeParams)) )
{
SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&spDevInfoData);
}

// Perform enable on config-specific profile
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.StateChange = DICS_ENABLE;
spPropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
spPropChangeParams.HwProfile = 0;
}
else
{
// Perform disable on config-specific profile
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.StateChange = DICS_DISABLE;
spPropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
spPropChangeParams.HwProfile = 0;
}

if(!SetupDiSetClassInstallParams(hDevInfo,
&spDevInfoData,
&spPropChangeParams.ClassInstallHeader,
sizeof(spPropChangeParams)) ||
!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&spDevInfoData) )
{
// Failed to invoke DIF_PROPERTYCHANGE
}
else
{
// Config specific profile sets reboot flag if it needs reboot.
devParams.cbSize = sizeof(devParams);
if(SetupDiGetDeviceInstallParams(hDevInfo,&spDevInfoData,&devParams) &&
(devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT)) )
{
// It needs reboot or restart
}
else
{
// We are done successfully.
return TRUE;
}
}
return FALSE;
}