internal unsafe void ClearCache() { // Tell the driver to search for any new SSIDs // and return them on the next OID_802_11_BSSID_LIST // message. uint dwBytesReturned = 0; NDISUIO_QUERY_OID queryOID = new NDISUIO_QUERY_OID(0); IntPtr ndisAccess; bool retval; // Attach to NDISUIO. ndisAccess = FileEx.CreateFile( NDISUIOPInvokes.NDISUIO_DEVICE_NAME, FileAccess.All, FileShare.None, FileCreateDisposition.OpenExisting, NDISUIOPInvokes.FILE_ATTRIBUTE_NORMAL | NDISUIOPInvokes.FILE_FLAG_OVERLAPPED); if ((int)ndisAccess == FileEx.InvalidHandle) { // The operation failed. Leave us empty. return; } // Send message to driver. byte[] namestr = System.Text.Encoding.Unicode.GetBytes(adapter.Name + '\0'); fixed(byte *name = &namestr[0]) { // Get Signal strength queryOID.ptcDeviceName = name; queryOID.Oid = NDISUIOPInvokes.OID_802_11_BSSID_LIST_SCAN; // 0x0D01011A retval = NDISUIOPInvokes.DeviceIoControl(ndisAccess, NDISUIOPInvokes.IOCTL_NDISUIO_SET_OID_VALUE, // 0x120814 queryOID, queryOID.Size, queryOID, queryOID.Size, ref dwBytesReturned, IntPtr.Zero); } if (retval) { // The call went fine. There is no return // data. } else { // There was an error. int err = MarshalEx.GetLastWin32Error(); // ToDo: Additional error processing. } queryOID = null; FileEx.CloseHandle(ndisAccess); }
internal unsafe void RefreshList(Boolean clearCache) { // If we are to clear the driver's cache of SSID // values, call the appropriate method. //Console.WriteLine("Entering RefreshList"); if (clearCache) { this.ClearCache(); // This seems to be needed to avoid having // a list of zero elements returned. System.Threading.Thread.Sleep(1000); } this.List.Clear(); // Retrieve a list of NDIS_802_11_BSSID_LIST // structures from the driver. We'll parse that // list and populate ourselves based on the data // that we find there. uint dwBytesReturned = 0; NDISUIO_QUERY_OID queryOID = new NDISUIO_QUERY_OID(6000 /* TESTING JFK was 2000 */); IntPtr ndisAccess; bool retval; // Attach to NDISUIO. ndisAccess = FileEx.CreateFile( NDISUIOPInvokes.NDISUIO_DEVICE_NAME, FileAccess.All, FileShare.None, FileCreateDisposition.OpenExisting, NDISUIOPInvokes.FILE_ATTRIBUTE_NORMAL | NDISUIOPInvokes.FILE_FLAG_OVERLAPPED); if ((int)ndisAccess == FileEx.InvalidHandle) { Console.WriteLine("Attach to NDISUIO Failed"); // The operation failed. Leave us empty. return; } // Get Signal strength byte[] namestr = System.Text.Encoding.Unicode.GetBytes(adapter.Name + '\0'); fixed(byte *name = &namestr[0]) { // Get Signal strength queryOID.ptcDeviceName = name; queryOID.Oid = NDISUIOPInvokes.OID_802_11_BSSID_LIST; // 0x0D010217 retval = NDISUIOPInvokes.DeviceIoControl(ndisAccess, NDISUIOPInvokes.IOCTL_NDISUIO_QUERY_OID_VALUE, // 0x00120804 queryOID, queryOID.Size, queryOID, queryOID.Size, ref dwBytesReturned, IntPtr.Zero); } if (retval) { // Now we need to parse the incoming data into // suitable representations of the SSIDs. // Figure out how many SSIDs there are. NDIS_802_11_BSSID_LIST rawlist = new NDIS_802_11_BSSID_LIST(queryOID.Data); for (int i = 0; i < rawlist.NumberOfItems; i++) { // Get the next raw item from the list. NDIS_WLAN_BSSID bssid = rawlist.Item(i); // Using the raw item, create a cooked // SSID item. AccessPoint ssid = new AccessPoint(bssid); // Add the new item to this. this.List.Add(ssid); } } else { // We might just need more room. // For now, we just leave the list empty. // ToDo: Additional error processing. Console.WriteLine("ERROR Buffer Too Small"); //You'll notice here there should be some sort of error contol but there isn't. //We simply don't have enough room. } }
internal void StatusThread() { // Ask NDISUIO to send us notification messages for our // adapter. IntPtr ndisAccess = FileEx.CreateFile( NDISUIOPInvokes.NDISUIO_DEVICE_NAME, FileAccess.All, FileShare.None, FileCreateDisposition.OpenExisting, NDISUIOPInvokes.FILE_ATTRIBUTE_NORMAL | NDISUIOPInvokes.FILE_FLAG_OVERLAPPED); if ((int)ndisAccess == FileEx.InvalidHandle) { return; } NDISUIO_REQUEST_NOTIFICATION ndisRequestNotification = new NDISUIO_REQUEST_NOTIFICATION(); ndisRequestNotification.hMsgQueue = mq.Handle; ndisRequestNotification.dwNotificationTypes = NDISUIOPInvokes.NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION | NDISUIOPInvokes.NDISUIO_NOTIFICATION_MEDIA_CONNECT | NDISUIOPInvokes.NDISUIO_NOTIFICATION_MEDIA_DISCONNECT | NDISUIOPInvokes.NDISUIO_NOTIFICATION_BIND | NDISUIOPInvokes.NDISUIO_NOTIFICATION_UNBIND; UInt32 xcount = 0; if (!NDISUIOPInvokes.DeviceIoControl(ndisAccess, NDISUIOPInvokes.IOCTL_NDISUIO_REQUEST_NOTIFICATION, ndisRequestNotification.getBytes(), NDISUIO_REQUEST_NOTIFICATION.Size, null, 0, ref xcount, IntPtr.Zero)) { System.Diagnostics.Debug.WriteLine(this, "Error in DeviceIoControl to request notifications!"); } // Each notification will be of this type. NDISUIO_DEVICE_NOTIFICATION ndisDeviceNotification = new NDISUIO_DEVICE_NOTIFICATION(); // Wait for the queue to be signaled. When it is, decode // the message and call any listeners for it. If the // queue closes suddenly, that's our cue to exit, shutting // down NDISUIO notifications before we leave. PointToPointMsgQueue q = mq; while (mq != null) // Check the global object here. { // Wait. On return, true indicates that the queue is // signaled; false is a chance to check whether we should // exit. if (q.Wait(-1)) { // Read the event data. int bytes = 0; PointToPointMsgQueueFlags readFlags = 0; if (q.ReadMsgQueue(ndisDeviceNotification.getBytes(), NDISUIO_DEVICE_NOTIFICATION.Size, ref bytes, -1, ref readFlags)) { // Handle the event. OnAdapterNotification(new AdapterNotificationArgs( ndisDeviceNotification.ptcDeviceName, (NdisNotificationType)ndisDeviceNotification.dwNotificationType)); } } else { System.Diagnostics.Debug.WriteLine(this, "mq is null in monitoring thread. Exiting..."); } } System.Diagnostics.Debug.WriteLine(this, "exiting AdapterStatusMonitor thread."); if (!NDISUIOPInvokes.DeviceIoControl(ndisAccess, NDISUIOPInvokes.IOCTL_NDISUIO_CANCEL_NOTIFICATION, null, 0, null, 0, ref xcount, IntPtr.Zero)) { System.Diagnostics.Debug.WriteLine(this, "Error in DeviceIoControl to stop notifications!"); // ???? } // Don't forget to close our handle to NDISUIO. FileEx.CloseHandle(ndisAccess); }