#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
#include <malloc.h>

#include <winerror.h>
#include <winsock.h>

#include <ntddndis.h>
#include "nuiouser.h"

#ifndef NDIS_STATUS
#define NDIS_STATUS     ULONG
#endif

#define DEBUGP(stmt)    printf stmt

#define PRINTF(stmt)    printf stmt

#ifndef MAC_ADDR_LEN
#define MAC_ADDR_LEN                    6
#endif

#define MAX_NDIS_DEVICE_NAME_LEN        256
HANDLE
OpenHandle(
    CHAR    *pDeviceName
)
{
    DWORD   DesiredAccess;
    DWORD   ShareMode;
    LPSECURITY_ATTRIBUTES   lpSecurityAttributes = NULL;

    DWORD   CreationDistribution;
    DWORD   FlagsAndAttributes;
    HANDLE  TemplateFile;
    HANDLE  Handle;
    DWORD   BytesReturned;

    DesiredAccess = GENERIC_READ|GENERIC_WRITE;
    ShareMode = 0;
    CreationDistribution = OPEN_EXISTING;
    FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
    TemplateFile = (HANDLE)INVALID_HANDLE_VALUE;

    Handle = CreateFile(
                pDeviceName,
                DesiredAccess,
                ShareMode,
                lpSecurityAttributes,
                CreationDistribution,
                FlagsAndAttributes,
                TemplateFile
            );
    if (Handle == INVALID_HANDLE_VALUE)
    {
        DEBUGP(("Creating file failed, error %x\n", GetLastError()));
        return Handle;
    }
    //
    //  Wait for the driver to finish binding.
    //
    if (!DeviceIoControl(
                Handle,
                IOCTL_NDISPROT_BIND_WAIT,
                NULL,
                0,
                NULL,
                0,
                &BytesReturned,
                NULL))
    {
        DEBUGP(("IOCTL_NDISIO_BIND_WAIT failed, error %x\n", GetLastError()));
        CloseHandle(Handle);
        Handle = INVALID_HANDLE_VALUE;
    }

    return (Handle);
}


BOOL
OpenNdisDevice(     
    HANDLE  Handle,
    CHAR   *pDeviceName
)
{
    WCHAR   wNdisDeviceName[MAX_NDIS_DEVICE_NAME_LEN];
    INT     wNameLength;
    INT     NameLength = strlen(pDeviceName);
    DWORD   BytesReturned;
    INT     i;


    //
    // Convert to unicode string - non-localized...
    //
    wNameLength = 0;
    for (i = 0; i < NameLength && i < MAX_NDIS_DEVICE_NAME_LEN-1; i++)
    {
        wNdisDeviceName[i] = (WCHAR)pDeviceName[i];
        wNameLength++;
    }
    wNdisDeviceName[i] = L'\0';

    printf("Trying to access NDIS Device: %ws\n", wNdisDeviceName);

    return (DeviceIoControl(
                Handle,
                IOCTL_NDISPROT_OPEN_DEVICE,
                (LPVOID)&wNdisDeviceName[0],
                wNameLength*sizeof(WCHAR),
                NULL,
                0,
                &BytesReturned,
                NULL));

}


BOOL GetSignalStrength(HANDLE  Handle, LONG * plRssi){
	UCHAR					QueryBuffer[1024];
	PNDISPROT_QUERY_OID		pQueryOid;
    DWORD       BytesReturned;

	pQueryOid = (PNDISPROT_QUERY_OID)&QueryBuffer[0];
	pQueryOid->Oid = OID_802_11_RSSI;

	if (DeviceIoControl(Handle,
						IOCTL_NDISPROT_QUERY_OID_VALUE,
						(LPVOID) &QueryBuffer[0],
						sizeof(QueryBuffer),
						(LPVOID) &QueryBuffer[0],
						sizeof(QueryBuffer),
						&BytesReturned,
						NULL))
	{
		printf("IOCTL GET_RSSI succeeded\n");
		memcpy(plRssi, &pQueryOid->Data[0], sizeof(NDIS_802_11_RSSI));
		return TRUE;
	}
	else
	{
		printf("IOCTL GET_RSSI failed: %d\n", GetLastError());
		return FALSE;
	}
}


VOID __cdecl
main(
    INT         argc,
    CHAR        *argv[]
)
{
    HANDLE      DeviceHandle;
	CHAR *          pNdisDeviceName = "temp";
	LONG	lSignalStrength = 0;


	if (argc < 2){
		printf ("getSignalStrength <DeviceName>\n");
		printf ("hint: try getDevices.exe to get the name of the devices\n");
		exit(0);
	}

    pNdisDeviceName = argv[argc-1];




    pNdisDeviceName = argv[argc-1];

    DeviceHandle = INVALID_HANDLE_VALUE;

	DeviceHandle = OpenHandle("\\\\.\\\\NdisProt");
    if (!OpenNdisDevice(DeviceHandle, pNdisDeviceName)){
            printf("Failed to access %s\n", pNdisDeviceName);
            exit(0);
    }

	printf("\n\n");
	if (GetSignalStrength(DeviceHandle, &lSignalStrength)){
		printf("SignalStrength: %d\n", lSignalStrength);
	}
	printf("\n\n");
	exit(1);
}

