• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2317
  • Last Modified:

NDISUIO_NOTIFICATION_MEDIA_CON­NECT/DISCONNECT problem

hi Expert:

I want to detect the NIC media status when connection states change.
So register the notification of NDISUIO_NOTIFICATION_MEDIA_CONNECT and
NDISUIO_NOTIFICATION_MEDIA_DISCONNECT.


When I power off access point , display message as below:

Media disconnected. --> correct
Media connect.       --> ??
Media disconnected.
Media connect.


I don't know what's happen?
Why the status of media by connected that has detected ?
What's wrong about my code ?


My platform is pocket pc 2003.


//initialization
hThread = CreateThread(NULL,0,DoWaitNotifThread,hWnd,0,(DWORD *)&rc);


DWORD WINAPI DoWaitNotifThread(PVOID pArg)
{
        HWND    hWnd;
        HANDLE  hMsgQueue = NULL;
        HRESULT         hr = S_OK;
        // Create the ndis message queue
        MSGQUEUEOPTIONS msgQueueOptions = {0};
        NDISUIO_REQUEST_NOTIFICATION ndisRequestNotification = {0};
        NDISUIO_DEVICE_NOTIFICATION     sDeviceNotification;
        DWORD   dwBytesReturned;
        DWORD   dwFlags;
        TCHAR   szOut[MAX_BUFFER_LENGTH];


        hWnd = (HWND)pArg;


        hr = HandleCurrentDevices();
        if(FAILED(hr))
        {
                wcscpy(szOut,TEXT("Could not handle initial Ndis devices"));
                SendMessage(hWnd,MYMSG_ADDLINE,-1,(LPARAM)szOut);
                return -1;
        }


  do{
           msgQueueOptions.dwSize       = sizeof(MSGQUEUEOPTIONS);
           msgQueueOptions.dwFlags      = 0;
           msgQueueOptions.dwMaxMessages        = 25;
           msgQueueOptions.cbMaxMessage= sizeof(NDISUIO_DEVICE_NOTIFICATION);
           msgQueueOptions.bReadAccess          = TRUE;


           hMsgQueue = CreateMsgQueue(
                                  NULL,
                                  &msgQueueOptions);


          if (hMsgQueue == NULL)
          {
        wcscpy(szOut,TEXT("Could not create message queue for Ndis notifications"));
        SendMessage(hWnd,MYMSG_ADDLINE,-1,(LPARAM)szOut);
        break;
          }


        ndisRequestNotification.hMsgQueue       = hMsgQueue;
        ndisRequestNotification.dwNotificationTypes = NDISUIO_NOTIFICATION_MEDIA_CONNECT |
                                                                           NDISUIO_NOTIFICATION_MEDIA_DISCONNECT;

        if (!DeviceIoControl(g_hNdisUio,
                                     IOCTL_NDISUIO_REQUEST_NOTIFICATION,
                                     &ndisRequestNotification,
                                     sizeof(NDISUIO_REQUEST_NOTIFICATION),
                                     NULL,
                                     0,
                                     NULL,
                                     NULL))
        {
                wcscpy(szOut,TEXT("Error invoking Ndis Ioctl method"));
                SendMessage(hWnd,MYMSG_ADDLINE,-1,(LPARAM)szOut);
                break;
        }


        //
        //      NDISUIO takes it well, now party on it..
        //
        while(1)
        {
              while (WaitForSingleObject(hMsgQueue,INFINITE) == WAIT_OBJECT_0)
              {


                  while (ReadMsgQueue(
                                    hMsgQueue,
                                    &sDeviceNotification,
                                   sizeof(NDISUIO_DEVICE_NOTIFICATION),
                                   &dwBytesReturned,
                                   1,
                                   &dwFlags))
                   {
                memset(szOut,0,MAX_BUFFER_LENGTH);
                switch(sDeviceNotification.dwNotificationType)
                {
                    case NDISUIO_NOTIFICATION_MEDIA_CONNECT:
                         wcscpy(szOut,TEXT("Media connected"));
                         break;
                     case NDISUIO_NOTIFICATION_MEDIA_DISCONNECT:
                        wcscpy(szOut,TEXT("Msg Close ,Media disconnected"));
                        break;
                    }
                    SendMessage(hWnd,MYMSG_ADDLINE,-1,(LPARAM)szOut);  
                     break;
                } //while readMsg

              }//while waitForSingleObject

        }


   }while(FALSE);


   if(hMsgQueue)
           CloseHandle(hMsgQueue);
} // DoWaitNotifThread


Thanks so much!

                    Mag
0
maghcc
Asked:
maghcc
  • 3
  • 2
1 Solution
 
opanzaCommented:
Hi,

If WaitForSingleObject(hMsgQueue,INFINITE) returns anything apart from WAIT_OBJECT_0 (hMsgQueue signaled -> data has been put into the queue), then it won't get into the ReadMsgQueue loop again.

This ReadMsgQueue loop is not such a loop since it always breaks its execution after the switch statement, whatever the dwNotificationType value is:

...

     SendMessage(hWnd,MYMSG_ADDLINE,-1,(LPARAM)szOut);  
     break;
} // while readMsg

...

So maybe the ReadMsgQueue function fails for some reason (ERROR_INSUFFICIENT_BUFFER, ERROR_PIPE_NOT_CONNECTED, ERROR_TIMEOUT) and does not reset the signal. Or maybe the WaitForSingleObject function fails and is returning WAIT_FAILED.

Cheers.
0
 
maghccAuthor Commented:
Hi Expert :

I want to detect the network status. I hope the detection that's persists.
When the network is disconnected , it will show message 'disconnected'.
When the network is connected, it will show message 'connected'.
So I create the thread to do this detection.

When I do some testing and have some questions.

Testing 1 : First power off access point , the network disconnected.
Into the ReadMsgQueue loop , the first status is NIC disconnected, that's correct.
If I don't use 'break' statement, it will continue to execute ReadMsgQueue loop, the second status is NIC connected.
I call the GetLastError() to get the value is 0.
Why ? That's my first question.

Testing 2 : Changed the dwNotificationTypes ,
ndisRequestNotification.dwNotificationTypes = NDISUIO_NOTIFICATION_MEDIA_CONNECT;

call ReadMsgQueue() to receive the NIC signal,
The network status should be disconnected ,when I power off accession point.
But the message queue always received the NIC status that is connected.

I call the GetLastError() to get the value is 0.

That's my second quesion.


Pleae Help me !! Thanks very much !
0
 
maghccAuthor Commented:
Nobody can answer this question ?

Please help me ! . thanks very much.

                          Mag
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
opanzaCommented:
A couple of ideas:

- You don't initialise sDeviceNotification before using ReadMsgQueue. You may want to use memset( &sDeviceNotification, 0, sizeof( sDeviceNotification ) ), and then set sDeviceNotification.ptcDeviceName to the device name.

- Could you also initialise dwNotificationType to 0 before using ReadMsgQueue? You may have a situation where you are not reading anything (dwTimeout is 1 millisecond) but you still have the previous data. You can also try to set dwTimeout to INFINITE and wait for a connection event to happen.
0
 
maghccAuthor Commented:
Hi expert :

Thanks for your advice.

I think that it's should be solved my problem.

thanks so much!

           Mag

0
 
Frog153Commented:
Do you any idea why when i set the SSID to my adapter NDISUIO_NOTIFICATION_MEDIA_CON­NECT newer show up!!! My code is and dwTimeout = 10000:

BOOL WaitForMediaConnectNotification(HANDLE hDevice, LPCTSTR pszAdapter, DWORD dwTimeout)
{
      MSGQUEUEOPTIONS msqOptions = {0};
      msqOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
      msqOptions.dwFlags = 0;
      msqOptions.dwMaxMessages = 25;
      msqOptions.cbMaxMessage = sizeof(NDISUIO_DEVICE_NOTIFICATION);
      msqOptions.bReadAccess = TRUE;

      HANDLE hMsgQueue = CreateMsgQueue(NULL, &msqOptions);
      if (hMsgQueue == NULL)
      {
            DWORD dwError = GetLastError();
            return FALSE;
      }

      NDISUIO_REQUEST_NOTIFICATION reqNotification = {0};
      reqNotification.hMsgQueue = hMsgQueue;
      reqNotification.dwNotificationTypes = NDISUIO_NOTIFICATION_MEDIA_CONNECT;

      DWORD dwBytesReturned = 0;

      if (!DeviceIoControl(
            hDevice, IOCTL_NDISUIO_REQUEST_NOTIFICATION,
            &reqNotification, sizeof(reqNotification),
            NULL, 0,
            &dwBytesReturned, NULL))
      {
            DWORD dwError = GetLastError();

            CloseHandle(hMsgQueue);
            return FALSE;
      }

      BOOL bConnected = FALSE;

      if (WaitForSingleObject(hMsgQueue, dwTimeout) == WAIT_OBJECT_0)
      {
            NDISUIO_DEVICE_NOTIFICATION deviceNotification = {0};
            DWORD dwNumberOfBytesRead = 0, dwFlags = 0;

            if (ReadMsgQueue(hMsgQueue, &deviceNotification, sizeof(deviceNotification),
                  &dwNumberOfBytesRead, 0, &dwFlags))
            {
                  bConnected =
                        deviceNotification.dwNotificationType == NDISUIO_NOTIFICATION_MEDIA_CONNECT;
            }
      }

      if (!DeviceIoControl(
            hDevice, IOCTL_NDISUIO_CANCEL_NOTIFICATION,
            NULL, 0,
            NULL, 0,
            &dwBytesReturned, NULL))
      {
            DWORD dwError = GetLastError();

            CloseHandle(hMsgQueue);
            return FALSE;
      }

      CloseHandle(hMsgQueue);

      if (!bConnected)
            return FALSE;

      return TRUE;
}
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now