1a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet/*
2a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * Copyright (C) 2009 The Android Open Source Project
3a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet *
4a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * Licensed under the Apache License, Version 2.0 (the "License");
5a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * you may not use this file except in compliance with the License.
6a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * You may obtain a copy of the License at
7a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet *
8a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet *      http://www.apache.org/licenses/LICENSE-2.0
9a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet *
10a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * Unless required by applicable law or agreed to in writing, software
11a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * distributed under the License is distributed on an "AS IS" BASIS,
12a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * See the License for the specific language governing permissions and
14a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet * limitations under the License.
15a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet */
16a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet
17a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet#include "usb_vendors.h"
18a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet
19a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet#include <stdio.h>
20a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
21a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#ifdef _WIN32
22a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#  define WIN32_LEAN_AND_MEAN
23a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#  include "windows.h"
24a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#  include "shlobj.h"
25a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#else
26a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#  include <unistd.h>
27a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#  include <sys/stat.h>
28a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#endif
29a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
30a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#include "sysdeps.h"
31a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet#include "adb.h"
32a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet
33a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define ANDROID_PATH            ".android"
34a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define ANDROID_ADB_INI         "adb_usb.ini"
35a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
36a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define TRACE_TAG               TRACE_USB
37a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
38a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet// Google's USB Vendor ID
39a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define VENDOR_ID_GOOGLE        0x18d1
40a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet// HTC's USB Vendor ID
41a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define VENDOR_ID_HTC           0x0bb4
42de6f62a609120c3d9e4e53689c3b309842ec874bXavier Ducrohet// Samsung's USB Vendor ID
43de6f62a609120c3d9e4e53689c3b309842ec874bXavier Ducrohet#define VENDOR_ID_SAMSUNG       0x04e8
44de6f62a609120c3d9e4e53689c3b309842ec874bXavier Ducrohet// Motorola's USB Vendor ID
45de6f62a609120c3d9e4e53689c3b309842ec874bXavier Ducrohet#define VENDOR_ID_MOTOROLA      0x22b8
466ae9256322053354c7d2badccc0ce5c24b37c243Mike Lockwood// LG's USB Vendor ID
476ae9256322053354c7d2badccc0ce5c24b37c243Mike Lockwood#define VENDOR_ID_LGE           0x1004
486ae9256322053354c7d2badccc0ce5c24b37c243Mike Lockwood// Huawei's USB Vendor ID
496ae9256322053354c7d2badccc0ce5c24b37c243Mike Lockwood#define VENDOR_ID_HUAWEI        0x12D1
507953b89e8d68565d15791618146a712231683d09Robert CH Chou// Acer's USB Vendor ID
517953b89e8d68565d15791618146a712231683d09Robert CH Chou#define VENDOR_ID_ACER          0x0502
5223433b93d1acb01650c9480d9bb5d5d869ba4f79Xavier Ducrohet// Sony Ericsson's USB Vendor ID
5323433b93d1acb01650c9480d9bb5d5d869ba4f79Xavier Ducrohet#define VENDOR_ID_SONY_ERICSSON 0x0FCE
546170404867631317ab57c67bf074494e6e775556Mike Lockwood// Foxconn's USB Vendor ID
556170404867631317ab57c67bf074494e6e775556Mike Lockwood#define VENDOR_ID_FOXCONN       0x0489
5637ddce736ce7700ee1e120f7371e6ee6a526f3caMike Lockwood// Dell's USB Vendor ID
5737ddce736ce7700ee1e120f7371e6ee6a526f3caMike Lockwood#define VENDOR_ID_DELL          0x413c
586ac5e192997478ae166981ddf66136c865d21a40Erik Gilling// Nvidia's USB Vendor ID
596ac5e192997478ae166981ddf66136c865d21a40Erik Gilling#define VENDOR_ID_NVIDIA        0x0955
601873adc2b12d5a9045bae90650bb331c7c7aa3c7Raphael// Garmin-Asus's USB Vendor ID
611873adc2b12d5a9045bae90650bb331c7c7aa3c7Raphael#define VENDOR_ID_GARMIN_ASUS   0x091E
62123331adeaed6c54e4869b0fd7001c5f1b19bdc4Takeshi Kishimoto// Sharp's USB Vendor ID
63123331adeaed6c54e4869b0fd7001c5f1b19bdc4Takeshi Kishimoto#define VENDOR_ID_SHARP         0x04dd
6401512aa3b0e3709e97054ffd1ff265a2d4193646Takeshi Kishimoto// ZTE's USB Vendor ID
6501512aa3b0e3709e97054ffd1ff265a2d4193646Takeshi Kishimoto#define VENDOR_ID_ZTE           0x19D2
668d2f91db21271a253bfe1bbe7716ff59e88572bdTakeshi Kishimoto// Kyocera's USB Vendor ID
678d2f91db21271a253bfe1bbe7716ff59e88572bdTakeshi Kishimoto#define VENDOR_ID_KYOCERA       0x0482
687c19bbe086b3cd81499829c0a79ed0ed0ae4fb16Xavier Ducrohet// Pantech's USB Vendor ID
697c19bbe086b3cd81499829c0a79ed0ed0ae4fb16Xavier Ducrohet#define VENDOR_ID_PANTECH       0x10A9
707c19bbe086b3cd81499829c0a79ed0ed0ae4fb16Xavier Ducrohet
71a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
72a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet/** built-in vendor list */
73a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohetint builtInVendorIds[] = {
74a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    VENDOR_ID_GOOGLE,
75a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    VENDOR_ID_HTC,
76de6f62a609120c3d9e4e53689c3b309842ec874bXavier Ducrohet    VENDOR_ID_SAMSUNG,
77de6f62a609120c3d9e4e53689c3b309842ec874bXavier Ducrohet    VENDOR_ID_MOTOROLA,
786ae9256322053354c7d2badccc0ce5c24b37c243Mike Lockwood    VENDOR_ID_LGE,
796ae9256322053354c7d2badccc0ce5c24b37c243Mike Lockwood    VENDOR_ID_HUAWEI,
807953b89e8d68565d15791618146a712231683d09Robert CH Chou    VENDOR_ID_ACER,
8123433b93d1acb01650c9480d9bb5d5d869ba4f79Xavier Ducrohet    VENDOR_ID_SONY_ERICSSON,
826170404867631317ab57c67bf074494e6e775556Mike Lockwood    VENDOR_ID_FOXCONN,
8337ddce736ce7700ee1e120f7371e6ee6a526f3caMike Lockwood    VENDOR_ID_DELL,
846ac5e192997478ae166981ddf66136c865d21a40Erik Gilling    VENDOR_ID_NVIDIA,
851873adc2b12d5a9045bae90650bb331c7c7aa3c7Raphael    VENDOR_ID_GARMIN_ASUS,
86123331adeaed6c54e4869b0fd7001c5f1b19bdc4Takeshi Kishimoto    VENDOR_ID_SHARP,
8701512aa3b0e3709e97054ffd1ff265a2d4193646Takeshi Kishimoto    VENDOR_ID_ZTE,
888d2f91db21271a253bfe1bbe7716ff59e88572bdTakeshi Kishimoto    VENDOR_ID_KYOCERA,
897c19bbe086b3cd81499829c0a79ed0ed0ae4fb16Xavier Ducrohet    VENDOR_ID_PANTECH,
90a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet};
91a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
92a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define BUILT_IN_VENDOR_COUNT    (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0]))
93a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
94a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet/* max number of supported vendor ids (built-in + 3rd party). increase as needed */
95a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#define VENDOR_COUNT_MAX         128
96a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
97a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohetint vendorIds[VENDOR_COUNT_MAX];
98a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohetunsigned vendorIdCount = 0;
99a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet
100a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohetint get_adb_usb_ini(char* buff, size_t len);
101a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
102a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohetvoid usb_vendors_init(void)
103a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet{
104a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    if (VENDOR_COUNT_MAX < BUILT_IN_VENDOR_COUNT) {
105a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        fprintf(stderr, "VENDOR_COUNT_MAX not big enough for built-in vendor list.\n");
106a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        exit(2);
107a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    }
108a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
109a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    /* add the built-in vendors at the beginning of the array */
110a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    memcpy(vendorIds, builtInVendorIds, sizeof(builtInVendorIds));
111a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
112a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    /* default array size is the number of built-in vendors */
113a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    vendorIdCount = BUILT_IN_VENDOR_COUNT;
114a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
115a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    if (VENDOR_COUNT_MAX == BUILT_IN_VENDOR_COUNT)
116a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        return;
117a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
118a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    char temp[PATH_MAX];
119a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    if (get_adb_usb_ini(temp, sizeof(temp)) == 0) {
120a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        FILE * f = fopen(temp, "rt");
121a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
122a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        if (f != NULL) {
123a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet            /* The vendor id file is pretty basic. 1 vendor id per line.
124a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet               Lines starting with # are comments */
125a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet            while (fgets(temp, sizeof(temp), f) != NULL) {
126a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                if (temp[0] == '#')
127a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                    continue;
128a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
129a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                long value = strtol(temp, NULL, 0);
130a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                if (errno == EINVAL || errno == ERANGE || value > INT_MAX || value < 0) {
131a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                    fprintf(stderr, "Invalid content in %s. Quitting.\n", ANDROID_ADB_INI);
132a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                    exit(2);
133a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                }
134a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
135a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                vendorIds[vendorIdCount++] = (int)value;
136a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
137a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                /* make sure we don't go beyond the array */
138a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                if (vendorIdCount == VENDOR_COUNT_MAX) {
139a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                    break;
140a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet                }
141a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet            }
142a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        }
143a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    }
144a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet}
145a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet
146a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet/* Utils methods */
147a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
148a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet/* builds the path to the adb vendor id file. returns 0 if success */
149a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohetint build_path(char* buff, size_t len, const char* format, const char* home)
150a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet{
151a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    if (snprintf(buff, len, format, home, ANDROID_PATH, ANDROID_ADB_INI) >= len) {
152a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        return 1;
153a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    }
154a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
155a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    return 0;
156a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet}
157a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
158a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet/* fills buff with the path to the adb vendor id file. returns 0 if success */
159a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohetint get_adb_usb_ini(char* buff, size_t len)
160a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet{
161a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#ifdef _WIN32
162a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    const char* home = getenv("ANDROID_SDK_HOME");
163a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    if (home != NULL) {
164a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        return build_path(buff, len, "%s\\%s\\%s", home);
165a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    } else {
166a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        char path[MAX_PATH];
167a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        SHGetFolderPath( NULL, CSIDL_PROFILE, NULL, 0, path);
168a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        return build_path(buff, len, "%s\\%s\\%s", path);
169a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet    }
170a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#else
171a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    const char* home = getenv("HOME");
172a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    if (home == NULL)
173a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet        home = "/tmp";
174a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet
175a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet    return build_path(buff, len, "%s/%s/%s", home);
176a481d096feba7cf6e61d54e416a68e2d46498df1Xavier Ducrohet#endif
177a09fbd164d2e088bc5433d310e25640ae048d47dXavier Ducrohet}
178