1
/****************************************************************************
2
**
3
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the tools applications of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17
**
18
** In addition, as a special exception, Nokia gives you certain additional
19
** rights. These rights are described in the Nokia Qt LGPL Exception
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21
**
22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
29
**
30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include "serenum.h"
43
#include <QByteArray>
44
#include <QString>
45
#include <QDebug>
46
#include <windows.h>
47
#include <windef.h>
48
#include <setupapi.h>
49
#include <devguid.h>
50
#include <winreg.h>
51
#include <shlwapi.h>
52
53
//{4d36e978-e325-11ce-bfc1-08002be10318}
54
//DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 );
55
56
QList<SerialPortId> enumerateSerialPorts(int)
57
{
58
    DWORD index=0;
59
    SP_DEVINFO_DATA info;
60
    GUID guid = GUID_DEVCLASS_PORTS;
61
    HDEVINFO infoset = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT);
62
    QString valueName(16384, 0);
63
    QList<SerialPortId> list;
64
65
    for (index=0;;index++) {
66
        ZeroMemory(&info, sizeof(SP_DEVINFO_DATA));
67
        info.cbSize = sizeof(SP_DEVINFO_DATA);
68
        if (!SetupDiEnumDeviceInfo(infoset, index, &info))
69
            break;
70
        QString friendlyName;
71
        QString portName;
72
        DWORD size=0;
73
        SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, 0, 0, &size);
74
        QByteArray ba(size, 0);
75
        if(SetupDiGetDeviceRegistryProperty(infoset, &info, SPDRP_FRIENDLYNAME, 0, (BYTE*)(ba.data()), size, 0)) {
76
            friendlyName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1);
77
        }
78
        HKEY key = SetupDiOpenDevRegKey(infoset, &info, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
79
        if(key != INVALID_HANDLE_VALUE) {
80
            //RegGetValue not supported on XP, SHRegGetValue not supported by mingw, so use the old method of enumerating all the values
81
            for (DWORD dwi=0;;dwi++) {
82
                DWORD vsize = valueName.size();
83
                if (ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, 0, &size)) {
84
                    if (valueName.startsWith("PortName")) {
85
                       QByteArray ba(size, 0);
86
                       vsize = valueName.size();
87
                       if(ERROR_SUCCESS == RegEnumValue(key, dwi, (WCHAR*)(valueName.data()), &vsize, 0, 0, (BYTE*)(ba.data()), &size)) {
88
                           portName = QString((const QChar*)(ba.constData()), ba.size() / 2 - 1);
89
                       }
90
                   }
91
                } else {
92
                    break;
93
                }
94
            }
95
            RegCloseKey(key);
96
        }
97
        SerialPortId id;
98
        id.portName = portName;
99
        id.friendlyName = friendlyName;
100
        list.append(id);
101
    }
102
    SetupDiDestroyDeviceInfoList(infoset);
103
    return list;
104
}