/*
* Copyright (c) 2013-15, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
*   of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
*   list of conditions and the following disclaimer in the documentation and/or
*   other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
*   contributors may be used to endorse or promote products derived from this
*   software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "stdafx.h"
#include "SerialList.h"

#define KEY_SERIALCOMM_PATH _T("HARDWARE\\DEVICEMAP\\SERIALCOMM")

// See SerialList.h for documentation of this method.
SerialList *g_pAllComDevices;

// See SerialList.h for documentation of this method.
void SerialList::ScanSerialDevices()
{
    if (m_serialDevices.size() != 0)
    {
        m_serialDevices.clear();
    }

    HKEY hKey;
    int i = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_SERIALCOMM_PATH, NULL, KEY_READ, &hKey);
    if (i == ERROR_SUCCESS)
    {
        int i = 0, status;
        TCHAR Name[128], Data[32];
        DWORD dNameLength, dDataLength;
        do
        {
            dNameLength = sizeof(Name);
            dDataLength = sizeof(Data);

            status = ::RegEnumValue(hKey, i, Name, &dNameLength, NULL, NULL, (PUCHAR)Data, &dDataLength);
            if ((status == ERROR_SUCCESS) && (dDataLength != 0))
            {
                m_serialDevices.push_back(SerialDevice(Data));
            }
            i++;
        } while (status != ERROR_NO_MORE_ITEMS);
    }
    ::RegCloseKey(hKey);

    SortSerialDevices();
}

// See SerialList.h for documentation of this method.
void SerialList::SortSerialDevices()
{
    size_t length = GetDeviceCount();
    for (size_t i = 0; i < length; i++)
    {
        for (size_t j = i + 1; j < length; j++)
        {
            if (GetDevice(i).GetNum() > GetDevice(j).GetNum())
            {
                std::swap(m_serialDevices[i], m_serialDevices[j]);
            }
        }
    }
}