Sample Code

Windows Driver Samples/ PLX9x5x PCI Driver/ C++/ test/ plx.cpp/

/*++

Copyright (c) Microsoft Corporation

Module Name:

    plx.cpp

Abstract:

    This module implements the PLX class which tests the DMA of PLX devices.

    Example usage:
        plx.exe /wr /wb=100         # write-then-read once with a buffer of 100 bytes
        plx.exe /thread             # repeat write-then-read for default 5000 millisecs.
        plx.exe /thread /time=1000  # repeat write-then-read for 1000 millisecs.

    NOTE: The /quite option will suppress most non-error messages.
    NOTE: The options and parameters are case sensitive.

Environment:

    User Mode Win2k or Later

--*/

#define INITGUID

#include "plx.hpp"

//
// Define the spin count to be used for critical sections. The value
// specified below is arbitrary. Change it based on your requirements.
//
#define SPIN_COUNT_FOR_CS       0x4000

int g_TimeUp =0;

DWORD WINAPI
ReadThreadProc(
    LPVOID lpParameter
    )
{
    ULONG bytes;
    PTHREAD_CONTEXT Context = (PTHREAD_CONTEXT)lpParameter;

    while(!g_TimeUp) {

        if(ReadFile(Context->hDevice,
                    Context->Buffer,
                    Context->BufferSize,
                    &bytes,
                    NULL)) {

            if (!Context->quite) {
                printf("Read sucessful.\n");
            }

        } else {

            printf("Read failed.\n");
            ExitProcess(1);
        }
    }
    ExitThread(0);
}

DWORD WINAPI
WriteThreadProc(
    LPVOID lpParameter
    )
{
    ULONG bytes;
    PTHREAD_CONTEXT Context = (PTHREAD_CONTEXT)lpParameter;

    while(!g_TimeUp) {

        if(WriteFile(Context->hDevice,
                     Context->Buffer,
                     Context->BufferSize,
                     &bytes,
                     NULL)) {

            if (!Context->quite) {
                printf("Write sucessful.\n");
            }

        } else {

            printf("Write failed.\n");
            ExitProcess(1);
        }
    }
    ExitThread(0);
}

int __cdecl
main(
    _In_              int argc,
    _In_reads_(argc) char* argv[]
    )
{
    PLX Plx;
    BOOL status = TRUE;
    ULONG test = MENU_TEST;

    if (!Plx.Initialize()) {
        printf("Failied to Initialize Test class.\n");
        printf("exit(%u)\n", Plx.Status);
        exit(Plx.Status);
    }

    if(argc > 1) {

        for(int i=1; (i < argc) && status; i++) {

            char delims[]   = "-/=";
            char delims2[]  = "=";
            char *command;
            char *data;
            char *state = NULL;

            data = NULL;

            #pragma prefast(suppress:6385, "i < argc-1 before it is incremented below");
            command =  strtok_s(argv[i], delims, &state);
            if(command == NULL) {
                status = FALSE;
                break;
            }

            if(strcmp(command, "rb") == 0) {

                data = strtok_s(NULL, delims2, &state);

                if (!data && i < argc-1) {
                    data = argv[++i];
                }

                ULONG size = atol(data);
                if (size > 0) {
                    Plx.SetReadBufferSize(size);
                } else {
                    status = FALSE;
                }

            } else if(strcmp(command, "wb") == 0) {

                ULONG size = 0;
                data = strtok_s(NULL, delims2, &state);

                if (!data && i < argc-1) {
                    data = argv[++i];
                }
                if (data) {
                    size = atol(data);
                }

                if (size > 0) {
                    Plx.SetWriteBufferSize(size);
                } else {
                    status = FALSE;
                }

            } else if (strcmp(command, "bs") == 0) {
                data = strtok_s(NULL, delims2, &state);

                if (!data && i < argc-1) {
                    data = argv[++i];
                }

                ULONG size = atol(data);
                if(size > 0) {
                    Plx.SetWriteBufferSize(size);
                } else {
                    status = FALSE;
                }

            } else if(strcmp(command, "wt") == 0) {

                test = WRITE_TEST;

            } else if(strcmp(command, "rt") == 0) {

                test = READ_TEST;

            } else if(strcmp(command, "quite") == 0) {

                Plx.Quite = TRUE;

            } else if(strcmp(command, "thread") == 0) {

                test = THREAD_TEST;

            } else if (strcmp(command, "time") == 0) {

                data = strtok_s(NULL, delims, &state);

                if(!data && i < argc-1) {
                    #pragma prefast(suppress:6385, "i < argc-1 before it is incremented");
                    data = argv[++i];
                }
                ULONG size = (NULL != data) ? atol(data) : 0;
                Plx.SetThreadLifeTime(size);

            } else {
                status = FALSE;
            }

            if (!Plx.Quite) {
                if (data) {
                    printf("Arg %d: Command: %s  Parameter: %s\n", i, command, data);
                } else {
                    printf("Arg %d: Command: %s\n", i, command);
                }
            }
        }
    }

    if (status) {

        switch (test) {
            case READ_TEST:
                Plx.ReadTest();
                break;

            case WRITE_TEST:
                Plx.WriteTest();
                break;

            case READ_WRITE_TEST:
                Plx.ReadWriteTest();
                break;

            case THREAD_TEST:
                Plx.ThreadedReadWriteTest();
                break;

            case MENU_TEST:
            default:
                Plx.Menu();
        }

    } else {

        printf("Invalid command line parameter.\n");
        Plx.Status = 1;
    }

    printf("exit(%u)\n", Plx.Status);

    exit( Plx.Status );
}

PLX::PLX()
{
    ReadBuffer = WriteBuffer = NULL;
    hDevInfo = pDeviceInterfaceDetail = NULL;
    hDevice = INVALID_HANDLE_VALUE;
    console = TRUE;
    Contexts = NULL;
    Threads = NULL;
    ProcessorCount = 0;
    CSInitialized = FALSE;
    ThreadTimer = 5000;  // 5000 milliseconds (5 seconds)

    Quite = FALSE;
    Status = 0;
}

PLX::~PLX()
{

    if (CSInitialized) {
        DeleteCriticalSection(&CriticalSection);
    }
    if (hDevInfo) {
        SetupDiDestroyDeviceInfoList(hDevInfo);
    }

    if (pDeviceInterfaceDetail) {
        free(pDeviceInterfaceDetail);
    }

    if (Contexts) {
        _Analysis_assume_(ProcessorCount <= ThreadCount);
        for(int i = 0; i < ProcessorCount; i++) {
            if (Contexts[i].Buffer) {
                delete Contexts[i].Buffer;
            }
        }

        delete Contexts;
        Contexts = NULL;
    }

    if (hDevice != INVALID_HANDLE_VALUE) {
        CloseHandle(hDevice);
        hDevice = INVALID_HANDLE_VALUE;
    }
}

BOOL
PLX::Initialize()
{
    BOOL retValue = TRUE;

    retValue = SetBufferSizes(DEFAULT_READ_BUFFER_SIZE);
    if (!retValue) {
        return retValue;
    }

    retValue = GetDevicePath();
    if (!retValue) {
        return retValue;
    }

    if (!CSInitialized) {
        retValue = InitializeCriticalSectionAndSpinCount(&CriticalSection, SPIN_COUNT_FOR_CS);
        if (!retValue) {
            printf("InitializeCritialSection failed.\n");
            Status = GetLastError();
            return retValue;
        }
        CSInitialized = TRUE;
    }

    return retValue;
}

void
PLX::Menu()
{
    int menu = -1;

    while(menu != 0 && pDeviceInterfaceDetail) {
        printf("\n"
               " 1- Read from device\n"
               " 2- Write from device\n"
               " 3- Read/Write from device\n"
               " 4- Read/Write Thread Test\n"
               " 5- Select new device\n"
               " 6- Change Buffer Size\n"
               " 7- Compare Read/Write Buffers\n"
               " 8- Display Read/Write Buffers\n"
               " 9- Change Thread Lifetime\n"
               "10- Command Line Options\n"
               " 0- Quit\n");

        if (scanf_s("%d", &menu) == 0) {
            break;
        }

        switch(menu) {
            case READ_TEST:                             // 1
                ReadTest();
                break;

            case WRITE_TEST:                            // 2
                WriteTest();
                break;

            case READ_WRITE_TEST:                       // 3
                ReadWriteTest();
                break;

            case THREAD_TEST:                           // 4
                ThreadedReadWriteTest();
                break;

            case DEVICE_PATH:                           // 5
                GetDevicePath();
                break;

            case SET_SIZE:                              // 6
                ULONG size;
                printf("\nEnter new buffer size: ");
                if (scanf_s("%u", &size) != 0) {
                    SetBufferSizes(size);
                }
                break;

            case COMPARE_BUFFERS:                       // 7
                CompareReadWriteBuffers();
                break;

            case DISPLAY_BUFFERS:                       // 8
                DisplayReadWriteBuffers();
                break;

            case THREAD_TIME:                           // 9
                printf("\nEnter new Thread Lifetime (ms): ");
                if (scanf_s("%u", &ThreadTimer) == 0) {
                    break;
                }
                break;

            case COMMAND_LINE:                          // 10
                printf("Command Line Options\n"
                       " Set Read Buffer Size:           '/rb=xx'\n"
                       " Set Write Buffer Size:          '/wb=xx'\n"
                       " Set Both Buffer Sizes:          '/bs=xx'\n"
                       " Perform Write Test:             '/wt'\n"
                       " Perform Read Test:              '/rt'\n"
                       " Perform Read/Write Test:        '/wr'\n"
                       " Perform Read/Write Thread Test: '/thread'\n");
                break;

            default:
                break;
        }
    }
}

BOOL
PLX::ThreadedReadWriteTest()
{
    BOOL status = TRUE;
    DWORD_PTR pAffinity, sAffinity;
    int i;

    HANDLE hThread;
    HANDLE hProcess = GetCurrentProcess();

    GetProcessAffinityMask(hProcess, &pAffinity, &sAffinity);
    ProcessorCount = 0;

    while(pAffinity) {
        ProcessorCount++;
        pAffinity = pAffinity >> 1;
    }

    if (ProcessorCount == 1) {
        ThreadCount = DEFAULT_THREAD_COUNT;
    } else {
        ThreadCount = ProcessorCount;
    }

    Contexts = new THREAD_CONTEXT[ThreadCount];
    Threads = new HANDLE[ThreadCount];

    if (Contexts == NULL || Threads == NULL) {
        return FALSE;
    }

    if (hDevice == INVALID_HANDLE_VALUE) {
        status = GetDeviceHandle();
    }

    if (!Quite) {
        printf("Creating %d threads...\n", ThreadCount);
    }

    pAffinity = 1;

    for(i = 0; i < ThreadCount; i++) {

        if ((i % 2) == 0) {

            //
            //  Create Read Thread
            //
            Contexts[i].hDevice = hDevice;
            Contexts[i].BufferSize = ReadBufferSize;
            Contexts[i].Buffer = new UCHAR[ReadBufferSize];
            Contexts[i].quite  = Quite;

            hThread = CreateThread(NULL,
                                   0,
                                   ReadThreadProc,
                                   &Contexts[i],
                                   0,
                                   NULL);

            if (NULL == hThread) {
                printf( "Failed to create thread %d\n", i );
                this->Status = 1;
                break;

            } else {
                Threads[i] = hThread;
            }

        } else {

            //
            //  Create Write Thread
            //
            Contexts[i].hDevice = hDevice;
            Contexts[i].BufferSize = WriteBufferSize;
            Contexts[i].Buffer = new UCHAR[WriteBufferSize];
            Contexts[i].quite  = Quite;

            hThread = CreateThread(NULL,
                                   0,
                                   WriteThreadProc,
                                   &Contexts[i],
                                   0,
                                   NULL);

            if (NULL == hThread) {
                printf( "Failed to create thread %d\n", i );
                this->Status = 1;
                break;

            } else {
                Threads[i] = hThread;
            }
        }

        //
        //  Set Affinity
        //
        SetThreadAffinityMask(Threads[i], pAffinity);

        pAffinity = pAffinity << 1;
    }

    if (i != ThreadCount) {

        //
        // some create thread failed, bail out
        //
        printf( "Some CreateThread was failed, stop\n" );
        g_TimeUp = 1;

    } else {

        //
        // wait till either all quit or time is due
        //
        DWORD error;

        error = WaitForMultipleObjects(i, Threads, TRUE, ThreadTimer);

        if (error == WAIT_TIMEOUT) {

            //
            // Stop the threads if time is up
            //
            g_TimeUp = 2;
            error = WaitForMultipleObjects(i, Threads, TRUE, 100000) ;

            if (error) {
                printf("WaitForMultipleObjects[%d] error %u\n", i, error);
            }
        } else {
            if (error) {
                printf("WaitForMultipleObjects[%d] error %u\n", i, error);
            }
        }
    }

    if (Contexts) {
        for (i = 0; i < ThreadCount; i++) {
            if (Contexts[i].Buffer) {
                delete Contexts[i].Buffer;
            }
        }

        delete Contexts;
        Contexts = NULL;
    }

    if (hDevice != INVALID_HANDLE_VALUE) {
        CloseHandle(hDevice);
        hDevice = INVALID_HANDLE_VALUE;
    }

    return status;
}

BOOL
PLX::ReadTest()
{
    BOOL status = TRUE;
    ULONG bytes = 0;

    if (!ReadBuffer) {
        status = FALSE;
    }

    if ((status == TRUE) && (hDevice == INVALID_HANDLE_VALUE)) {
        status = GetDeviceHandle();
    }

    if (status) {
        if (ReadFile(hDevice,
                    ReadBuffer,
                    ReadBufferSize,
                    &bytes,
                    NULL)){

            EnterCriticalSection(&CriticalSection);
            if (!Quite) {
                printf("Read sucessful.\n");
            }
            LeaveCriticalSection(&CriticalSection);

        } else {

            EnterCriticalSection(&CriticalSection);
            printf("Read failed.\n");
            this->Status = 1;
            LeaveCriticalSection(&CriticalSection);
        }
    }

    if (hDevice != INVALID_HANDLE_VALUE) {
        CloseHandle(hDevice);
        hDevice = INVALID_HANDLE_VALUE;
    }

    return status;
}

BOOL
PLX::WriteTest()
{
    ULONG bytes = 0;
    BOOL status = TRUE;

    if (!WriteBuffer) {
        status = FALSE;
    }

    if ((status == TRUE) && (hDevice == INVALID_HANDLE_VALUE)) {
        status = GetDeviceHandle();
    }

    if (status) {
        FillMemory(WriteBuffer, WriteBufferSize, 0xAB);

        if (WriteFile(hDevice,
                      WriteBuffer,
                      WriteBufferSize,
                      &bytes,
                      NULL)) {

            EnterCriticalSection(&CriticalSection);
            if (!Quite) {
                printf("Write sucessful.\n");
            }
            LeaveCriticalSection(&CriticalSection);

        } else {

            EnterCriticalSection(&CriticalSection);
            printf("Write failed.\n");
            this->Status = 1;
            LeaveCriticalSection(&CriticalSection);
        }
    }

    if (hDevice != INVALID_HANDLE_VALUE) {
        CloseHandle(hDevice);
        hDevice = INVALID_HANDLE_VALUE;
    }

    return status;
}

BOOL
PLX::ReadWriteTest()
{
    return (WriteTest() && ReadTest() && CompareReadWriteBuffers());
}

BOOL
PLX::CompareReadWriteBuffers()
{
    BOOL status = TRUE;
    ULONG size;
    PUCHAR WTraverse;
    PUCHAR RTraverse;

    if (ReadBufferSize <= WriteBufferSize) {
        size = ReadBufferSize;
    } else {
        size = WriteBufferSize;
    }

    WTraverse = WriteBuffer;
    RTraverse = ReadBuffer;

    for(ULONG i = 0; i < size; i++) {
        if (*WTraverse++ != *RTraverse++) {
            status = FALSE;
        }
    }

    if (status) {
        if (!Quite) {
            printf("Buffers are identical\n");
        }
    } else {
        printf("Buffers not identical\n");
        this->Status = 1;
    }

    return status;
}

void
PLX::DisplayReadWriteBuffers()
{
    if (!Quite) {

        PUCHAR WTraverse;
        PUCHAR RTraverse;

        WTraverse = WriteBuffer;
        RTraverse = ReadBuffer;

        printf("Write: ");
        for(ULONG i = 0; i < WriteBufferSize; i++) {
            printf("%X ", *WTraverse++);
        }

        printf("\n\n\nRead: ");
        for(ULONG i = 0; i < ReadBufferSize; i++) {
            printf("%X ", *RTraverse++);
        }
        printf("\n");
    }
}

BOOL
PLX::SetReadBufferSize(ULONG size)
{
    BOOL status = TRUE;

    if (ReadBuffer) {
        free(ReadBuffer);
    }

    ReadBufferSize = size;

    ReadBuffer = (PUCHAR)malloc(ReadBufferSize);

    if (!ReadBuffer) {
        status = FALSE;
    }

    return status;
}

BOOL
PLX::SetWriteBufferSize(ULONG size)
{
    BOOL status = TRUE;

    if (WriteBuffer) {
        free(WriteBuffer);
    }

    WriteBufferSize = size;

    WriteBuffer = (PUCHAR)malloc(WriteBufferSize);

    if (!WriteBuffer) {
        status = FALSE;
    }

    return status;
}

BOOL
PLX::SetBufferSizes(ULONG size)
{
    BOOL status;

    status = SetReadBufferSize(size);
    if (status) {
        status = SetWriteBufferSize(size);
    }

    return status;
}

BOOL
PLX::GetDevicePath()
{
    SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
    SP_DEVINFO_DATA DeviceInfoData;

    ULONG size;
    int count, i, index;
    BOOL status = TRUE;
    TCHAR *DeviceName = NULL;
    TCHAR *DeviceLocation = NULL;

    //
    //  Retreive the device information for all PLX devices.
    //
    hDevInfo = SetupDiGetClassDevs(&GUID_PLX_INTERFACE,
                                   NULL,
                                   NULL,
                                   DIGCF_DEVICEINTERFACE |
                                   DIGCF_PRESENT);

    //
    //  Initialize the SP_DEVICE_INTERFACE_DATA Structure.
    //
    DeviceInterfaceData.cbSize  = sizeof(SP_DEVICE_INTERFACE_DATA);

    //
    //  Determine how many devices are present.
    //
    count = 0;
    while(SetupDiEnumDeviceInterfaces(hDevInfo,
                                      NULL,
                                      &GUID_PLX_INTERFACE,
                                      count++,  //Cycle through the available devices.
                                      &DeviceInterfaceData)
          );

    //
    // Since the last call fails when all devices have been enumerated,
    // decrement the count to get the true device count.
    //
    count--;

    //
    //  If the count is zero then there are no devices present.
    //
    if (count == 0) {
        printf("No PLX devices are present and enabled in the system.\n");
        this->Status = 1;
        return FALSE;
    }

    //
    //  Initialize the appropriate data structures in preparation for
    //  the SetupDi calls.
    //
    DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    //
    //  Loop through the device list to allow user to choose
    //  a device.  If there is only one device, select it
    //  by default.
    //
    i = 0;
    while (SetupDiEnumDeviceInterfaces(hDevInfo,
                                       NULL,
                                       (LPGUID)&GUID_PLX_INTERFACE,
                                       i,
                                       &DeviceInterfaceData)) {

        //
        // Determine the size required for the DeviceInterfaceData
        //
        SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                        &DeviceInterfaceData,
                                        NULL,
                                        0,
                                        &size,
                                        NULL);

        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("SetupDiGetDeviceInterfaceDetail failed, Error: %u", GetLastError());
            this->Status = 1;
            return FALSE;
        }

        pDeviceInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(size);

        if (!pDeviceInterfaceDetail) {
            printf("Insufficient memory.\n");
            this->Status = 1;
            return FALSE;
        }

        //
        // Initialize structure and retrieve data.
        //
        pDeviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        status = SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                                 &DeviceInterfaceData,
                                                 pDeviceInterfaceDetail,
                                                 size,
                                                 NULL,
                                                 &DeviceInfoData);

        free(pDeviceInterfaceDetail);

        if (!status) {
            printf("SetupDiGetDeviceInterfaceDetail failed, Error: %u", GetLastError());
            this->Status = 1;
            return status;
        }

        //
        //  Get the Device Name
        //  Calls to SetupDiGetDeviceRegistryProperty require two consecutive
        //  calls, first to get required buffer size and second to get
        //  the data.
        //
        SetupDiGetDeviceRegistryProperty(hDevInfo,
                                        &DeviceInfoData,
                                        SPDRP_DEVICEDESC,
                                        NULL,
                                        (PBYTE)DeviceName,
                                        0,
                                        &size);

        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("SetupDiGetDeviceRegistryProperty failed, Error: %u", GetLastError());
            this->Status = 1;
            return FALSE;
        }

        DeviceName = (TCHAR*) malloc(size);
        if (!DeviceName) {
            printf("Insufficient memory.\n");
            this->Status = 1;
            return FALSE;
        }

        status = SetupDiGetDeviceRegistryProperty(hDevInfo,
                                                  &DeviceInfoData,
                                                  SPDRP_DEVICEDESC,
                                                  NULL,
                                                  (PBYTE)DeviceName,
                                                  size,
                                                  NULL);
        if (!status) {
            printf("SetupDiGetDeviceRegistryProperty failed, Error: %u",
                   GetLastError());
            free(DeviceName);
            this->Status = 1;
            return status;
        }

        //
        //  Now retrieve the Device Location.
        //
        SetupDiGetDeviceRegistryProperty(hDevInfo,
                                         &DeviceInfoData,
                                         SPDRP_LOCATION_INFORMATION,
                                         NULL,
                                         (PBYTE)DeviceLocation,
                                         0,
                                         &size);

        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            DeviceLocation = (TCHAR*) malloc(size);

            if (DeviceLocation != NULL) {

                status = SetupDiGetDeviceRegistryProperty(hDevInfo,
                                                          &DeviceInfoData,
                                                          SPDRP_LOCATION_INFORMATION,
                                                          NULL,
                                                          (PBYTE)DeviceLocation,
                                                          size,
                                                          NULL);
                if (!status) {
                    free(DeviceLocation);
                    DeviceLocation = NULL;
                }
            }

        } else {
            DeviceLocation = NULL;
        }

        //
        // If there is more than one device print description.
        //
        if (count > 1 && console) {
            printf("%d- ", i);
        }

        printf("%s\n", DeviceName);

        if (DeviceLocation) {
            printf("        %s\n", DeviceLocation);
        }

        free(DeviceName);
        DeviceName = NULL;

        if (DeviceLocation) {
            free(DeviceLocation);
            DeviceLocation = NULL;
        }

        i++; // Cycle through the available devices.
    }

    //
    //  Select device.
    //
    index = 0;
    if (count > 1) {
        printf("\nSelect Device: ");

        if (scanf_s("%d", &index) == 0) {
            return ERROR_INVALID_DATA;
        }
    }

    //
    //  Get information for specific device.
    //
    status = SetupDiEnumDeviceInterfaces(hDevInfo,
                                    NULL,
                                    (LPGUID)&GUID_PLX_INTERFACE,
                                    index,
                                    &DeviceInterfaceData);

    if (!status) {
        printf("SetupDiEnumDeviceInterfaces failed, Error: %u", GetLastError());
        return status;
    }

    //
    // Determine the size required for the DeviceInterfaceData
    //
    SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                    &DeviceInterfaceData,
                                    NULL,
                                    0,
                                    &size,
                                    NULL);

    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        printf("SetupDiGetDeviceInterfaceDetail failed, Error: %u", GetLastError());
        this->Status = 1;
        return FALSE;
    }

    pDeviceInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(size);

    if (!pDeviceInterfaceDetail) {
        printf("Insufficient memory.\n");
        this->Status = 1;
        return FALSE;
    }

    //
    // Initialize structure and retrieve data.
    //
    pDeviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    status = SetupDiGetDeviceInterfaceDetail(hDevInfo,
                                             &DeviceInterfaceData,
                                             pDeviceInterfaceDetail,
                                             size,
                                             NULL,
                                             &DeviceInfoData);
    if (!status) {
        printf("SetupDiGetDeviceInterfaceDetail failed, Error: %u", GetLastError());
        this->Status = 1;
        return status;
    }

    return status;
}

BOOL
PLX::GetDeviceHandle()
{
    BOOL status = TRUE;

    if (pDeviceInterfaceDetail == NULL) {
        status = GetDevicePath();
    }
    if (pDeviceInterfaceDetail == NULL) {
        status = FALSE;
    }

    if (status) {

        //
        //  Get handle to device.
        //
        hDevice = CreateFile(pDeviceInterfaceDetail->DevicePath,
                             GENERIC_READ|GENERIC_WRITE,
                             FILE_SHARE_READ | FILE_SHARE_WRITE,
                             NULL,
                             OPEN_EXISTING,
                             0,
                             NULL);

        if (hDevice == INVALID_HANDLE_VALUE) {
            status = FALSE;
            printf("CreateFile failed.  Error:%u", GetLastError());
            this->Status = 1;
        }
    }

    return status;
}

void
PLX::SetThreadLifeTime(ULONG time)
{
    ThreadTimer = time;
}

Our Services

  • What our customers say about us?

© 2011-2024 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS