Makefile: remove spurious tab
[xcsoar.git] / src / Asset.cpp
blob73bc9abe9d71292a55f24793a9051aac33047a72
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Asset.hpp"
25 #include "Util/Macros.hpp"
26 #include "LogFile.hpp"
27 #include "UtilsSystem.hpp"
28 #include "LocalPath.hpp"
29 #include "IO/FileHandle.hpp"
30 #include "Util/CharUtil.hpp"
32 #if defined(WIN32) && (!defined(__GNUC__) || defined(_WIN32_WCE))
33 #include <windows.h>
34 #include <winioctl.h>
35 #endif
37 #include <windef.h> /* for MAX_PATH */
38 #include <string.h>
40 // Registration Data
41 TCHAR asset_number[100] = _T(""); //4G17DW31L0HY");
43 #ifdef HAVE_MODEL_TYPE
44 ModelType global_model_type = ModelType::GENERIC;
45 #endif
47 #ifdef _WIN32_WCE
48 static bool
49 SetAssetNumber(const TCHAR *p)
51 size_t length = 0;
52 while (length < ARRAY_SIZE(asset_number) - 1 && *p != _T('\0')) {
53 if (IsAlphaNumericASCII(*p))
54 asset_number[length++] = *p;
55 ++p;
58 if (length < 3) {
59 asset_number[0] = _T('\0');
60 return false;
63 return true;
65 #endif
67 static bool
68 ReadCompaqID()
70 #if defined(_WIN32_WCE)
71 PROCESS_INFORMATION pi;
73 if (CreateProcess(_T("\\windows\\CreateAssetFile.exe"), NULL, NULL, NULL,
74 FALSE, 0, NULL, NULL, NULL, &pi)) {
75 WaitForSingleObject(pi.hProcess, 1000);
76 CloseHandle(pi.hProcess);
77 CloseHandle(pi.hThread);
80 FileHandle file(_T("\\windows\\cpqAssetData.dat"), _T("rb"));
81 if (!file.IsOpen() || !file.Seek(976, SEEK_SET))
82 return false;
84 TCHAR buffer[ARRAY_SIZE(asset_number)];
85 size_t length = file.Read(buffer, ARRAY_SIZE(buffer) - 1, sizeof(buffer[0]));
86 buffer[length] = _T('\0');
87 return SetAssetNumber(buffer);
88 #else
89 return false;
90 #endif
93 static bool
94 ReadUUID()
96 #if defined(_WIN32_WCE) && defined(IOCTL_HAL_GET_DEVICEID) && defined(FILE_DEVICE_HAL)
97 BOOL fRes;
99 #define GUIDBuffsize 100
100 unsigned char GUIDbuffer[GUIDBuffsize];
102 int eLast = 0;
103 int i;
104 unsigned long uNumReturned=0;
105 int iBuffSizeIn=0;
106 unsigned long temp, Asset;
108 GUID Guid;
110 // approach followed: http://blogs.msdn.com/jehance/archive/2004/07/12/181116.aspx
111 // 1) send 16 byte buffer - some older devices need this
112 // 2) if buffer is wrong size, resize buffer accordingly and retry
113 // 3) take first 16 bytes of buffer and process. Buffer returned may be any size
114 // First try exactly 16 bytes, some older PDAs require exactly 16 byte buffer
116 asset_number[0]= '\0';
118 iBuffSizeIn = sizeof(Guid);
119 memset(GUIDbuffer, 0, iBuffSizeIn);
120 fRes = KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, GUIDbuffer,
121 iBuffSizeIn, &uNumReturned);
122 if(fRes == false) {
123 // try larger buffer
124 eLast = GetLastError();
125 if (ERROR_INSUFFICIENT_BUFFER != eLast)
126 return false;
127 else {
128 // wrong buffer
129 iBuffSizeIn = uNumReturned;
130 memset(GUIDbuffer, 0, iBuffSizeIn);
131 fRes = KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, GUIDbuffer,
132 iBuffSizeIn, &uNumReturned);
133 eLast = GetLastError();
135 if(fRes == false)
136 return false;
140 // here assume we have data in GUIDbuffer of length uNumReturned
141 memcpy(&Guid, GUIDbuffer, sizeof(Guid));
143 temp = Guid.Data2;
144 temp = temp << 16;
145 temp += Guid.Data3;
147 Asset = temp ^ Guid.Data1;
149 temp = 0;
150 for(i = 0; i < 4; i++) {
151 temp = temp << 8;
152 temp += Guid.Data4[i];
155 Asset = Asset ^ temp;
157 temp = 0;
158 for(i = 0; i < 4; i++) {
159 temp = temp << 8;
160 temp += Guid.Data4[i + 4];
163 Asset = Asset ^ temp;
165 TCHAR buffer[20];
166 _stprintf(asset_number, _T("%08X%08X"), Asset, Guid.Data1);
167 return SetAssetNumber(buffer);
168 #else
169 return false;
170 #endif
173 void
174 ReadAssetNumber()
176 if (ReadCompaqID()) {
177 LogFormat(_T("Asset ID: %s (compaq)"), asset_number);
178 } else if (ReadUUID()) {
179 LogFormat(_T("Asset ID: %s (uuid)"), asset_number);
180 } else {
181 _tcscpy(asset_number, _T("AAA"));
182 LogFormat(_T("Asset ID: %s (fallback)"), asset_number);