Fixed DevStudio 2003 build with memory check code.
[pwlib.git] / tools / msvc6chk / msvc6chk.cpp
blob5d7ab76151a8ac46be5002c22dc93c688f2760d8
1 // msvc6chk.cpp : Defines the entry point for the console application.
2 //
4 #include <stdio.h>
5 #include <windows.h>
7 #include "iostream.h"
8 #include "io.h"
9 #include "fcntl.h"
11 #include <string>
13 #define VERSION "1.0"
16 static char * dinkumwareCopyright =
17 "The files presented here are copyright © 1995-2000 by P.J. Plauger.\n"
18 "All rights reserved. They are for use only in conjunction with a valid\n"
19 "license for Microsoft Visual C++ V5.0 or V6.0. Microsoft Corporation is in\n"
20 "no way involved with the production or release of these files. The files are\n"
21 "offered on an `as is' basis. DINKUMWARE, LTD. AND P.J. PLAUGER MAKE NO\n"
22 "REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THESE FILES, EITHER\n"
23 "EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF\n"
24 "MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.\n"
25 "DINKUMWARE, LTD. AND P.J. PLAUGER SHALL NOT BE LIABLE FOR ANY DAMAGES\n"
26 "SUFFERED BY LICENSEE AS A RESULT OF USING THESE FILES.";
30 static struct FileUpgradeInfo {
31 HKEY key;
32 const char * registryBase;
33 const char * registryKey;
34 const char * filename;
35 unsigned int oldcrc;
37 const char * newFilename;
38 unsigned int newcrc;
40 char * copyright;
41 } fileInfo[] = {
42 { HKEY_LOCAL_MACHINE,
43 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
44 "ProductDir",
45 "INCLUDE\\DEQUE", 0x4229bfd5,
46 "UPGRADES/DEQUE", 0x11539af7,
47 dinkumwareCopyright
50 { HKEY_LOCAL_MACHINE,
51 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
52 "ProductDir",
53 "INCLUDE\\FSTREAM", 0x28f76291,
54 "UPGRADES/FSTREAM", 0xb9a507b4,
55 dinkumwareCopyright
58 { HKEY_LOCAL_MACHINE,
59 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
60 "ProductDir",
61 "INCLUDE\\LIST", 0x64487361,
62 "UPGRADES/LIST", 0xa97cc61b,
63 dinkumwareCopyright
66 { HKEY_LOCAL_MACHINE,
67 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
68 "ProductDir",
69 "INCLUDE\\VECTOR", 0x26ba0df5,
70 "UPGRADES/VECTOR", 0x35a94c52,
71 dinkumwareCopyright
74 { HKEY_LOCAL_MACHINE,
75 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
76 "ProductDir",
77 "INCLUDE\\XMEMORY", 0xa6ac2fb8,
78 "UPGRADES/XMEMORY", 0x52936ff7,
79 dinkumwareCopyright
82 { HKEY_LOCAL_MACHINE,
83 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
84 "ProductDir",
85 "INCLUDE\\XSTRING", 0x705ce397,
86 "UPGRADES/XSTRING", 0x6215f086,
87 dinkumwareCopyright
90 { HKEY_LOCAL_MACHINE,
91 "SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++",
92 "ProductDir",
93 "INCLUDE\\XTREE", 0xe64c6f6e,
94 "UPGRADES/XTREE", 0x07972076,
95 dinkumwareCopyright
98 { NULL }
101 static unsigned long crc_table[256];
103 void gen_crc32_table(void) /* build the crc table */
105 unsigned long crc, poly;
106 int i, j;
108 poly = 0xEDB88320L;
109 for (i = 0; i < 256; i++) {
110 crc = i;
111 for (j = 8; j > 0; j--) {
112 if (crc & 1)
113 crc = (crc >> 1) ^ poly;
114 else
115 crc >>= 1;
117 crc_table[i] = crc;
121 void init_crc32(unsigned long & crc)
123 crc = 0xFFFFFFFF;
127 void add_to_crc32(unsigned long & crc, unsigned char value)
129 crc = (crc >> 8) ^ crc_table[(crc^value) & 0xFF];
130 crc = crc ^ 0xFFFFFFFF;
133 bool CalculateCRCOfFile(const std::string & fn, unsigned long & crc32)
135 int file = ::open(fn.c_str(), O_RDONLY | O_BINARY);
136 if (file < 0)
137 return false;
139 init_crc32(crc32);
140 char ch;
141 while (read(file, &ch, 1))
142 add_to_crc32(crc32, ch);
143 ::close(file);
144 return true;
148 class RegKey
150 public:
151 RegKey()
153 key = NULL;
155 ~RegKey()
157 if (key != NULL)
158 RegCloseKey(key);
161 HKEY key;
165 int main(int argc, char * argv[])
167 cout << "PWLIB File Upgrader v" << VERSION << "\n"
168 << "Copyright (C) 2004 by Post Increment" << endl;
170 gen_crc32_table();
172 bool testFiles = false;
173 bool doUpgrade = false;
174 bool force = false;
176 if (argc > 1) {
177 if (strcmpi(argv[1], "test") == 0)
178 testFiles = true;
179 else if (strcmpi(argv[1], "upgrade") == 0)
180 doUpgrade = true;
181 else if (strcmpi(argv[1], "force") == 0) {
182 doUpgrade = true;
183 force = true;
187 int status = 0;
189 unsigned i;
190 for (i = 0; fileInfo[i].filename != NULL; ++i) {
191 FileUpgradeInfo & info = fileInfo[i];
193 char * infoKeyName = "(unknown)";
194 if (info.key == HKEY_CLASSES_ROOT)
195 infoKeyName = "HKEY_CLASSES_ROOT";
197 else if (info.key == HKEY_CURRENT_USER)
198 infoKeyName = "HKEY_CURRENT_USER";
200 else if (info.key == HKEY_LOCAL_MACHINE)
201 infoKeyName = "HKEY_LOCAL_MACHINE";
203 else if (info.key == HKEY_USERS)
204 infoKeyName = "HKEY_USERS";
206 // open registry key
207 RegKey key;
208 LONG stat = RegOpenKeyEx(info.key,
209 info.registryBase,
210 0, KEY_READ,
211 &key.key);
212 if (stat != ERROR_SUCCESS) {
213 cout << "Registry entry " << infoKeyName << "\\" << info.registryBase << " not found - error = " << stat << endl;
214 continue;
217 DWORD keyType;
218 char keyData[4096];
219 DWORD keyLen = sizeof(keyData);
220 if (RegQueryValueEx(key.key,
221 info.registryKey,
222 NULL,
223 &keyType,
224 (BYTE *)keyData, &keyLen) != ERROR_SUCCESS) {
225 cout << "Registry key " << infoKeyName << "\\" << info.registryBase << "\\" << info.registryKey << " not found" << endl;
226 continue;
229 std::string fn(keyData);
230 fn += '\\';
231 fn += info.filename;
233 unsigned long crc32;
234 if (!CalculateCRCOfFile(fn, crc32)) {
235 cout << fn.c_str() << "does not exist" << endl;
236 continue;
239 if (testFiles) {
240 unsigned long newcrc;
241 if (!CalculateCRCOfFile(info.newFilename, newcrc))
242 cout << info.newFilename << "does not exist" << endl;
243 else {
244 cout << hex << crc32 << dec << " = " << fn.c_str() << "\n"
245 << hex << newcrc << dec << " = " << info.newFilename << "\n"
246 << endl;
250 else if (crc32 == info.newcrc) {
251 cout << fn.c_str() << " already upgraded" << endl;
252 continue;
255 if (crc32 != info.oldcrc) {
256 cout << "WARNING: " << fn.c_str() << " has unknown CRC " << hex << crc32 << dec
257 << ", assuming it does NOT need upgrade." << endl;
258 continue;
261 // create name of backup file
262 std::string backupFn = fn + ".backup";
263 char buffer[4];
264 int count = 1;
265 for (;;) {
266 if (::access(backupFn.c_str(), 0) != 0)
267 break;
268 sprintf(buffer, "_%i.backup", count++);
269 backupFn = fn + std::string(buffer);
272 if (!doUpgrade) {
273 cout << "\nWARNING: the following file requires upgrading:\n"
274 << fn.c_str() << endl;
275 std::string cmd = argv[0];
276 int pos = cmd.rfind('\\');
277 if (pos != std::string::npos)
278 cmd.erase(0, pos+1);
279 pos = cmd.rfind('.');
280 if (pos != std::string::npos)
281 cmd.erase(pos);
282 cout << "Please run \"" << cmd.c_str() << " upgrade\" to upgrade this file" << endl;
283 status = 1;
284 continue;
287 cout << "\nWARNING: the following file requires upgrading:\n"
288 << fn.c_str() << endl;
290 if (info.copyright != NULL)
291 cout << "\n" << info.copyright << "\n" << endl;
293 if (!force) {
294 cout << "Upgrade file (y/n) ? " << flush;
295 char ch;
296 cin >> ch;
297 ch = toupper(ch);
298 if (ch != 'Y') {
299 cout << "Aborting upgrade." << endl;
300 continue;
304 // check that replacement file exists
305 if (::access(info.newFilename, 0) != 0) {
306 cout << "ERROR: new file " << info.newFilename << "not found - aborting upgrade" << endl;
307 status = 1;
308 continue;
311 // rename existing file
312 if (::rename(fn.c_str(), backupFn.c_str()) != 0) {
313 cout << "ERROR: rename of " << fn.c_str() << " to " << backupFn.c_str() << " failed" << endl;
314 status = 1;
315 continue;
318 // copy new file
319 if (!CopyFile(info.newFilename, fn.c_str(), true)) {
320 cout << "ERROR: copy of " << info.newFilename << " to " << fn.c_str() << " failed\n"
321 << " reverting " << backupFn.c_str() << " to " << fn.c_str() << endl;
322 ::unlink(fn.c_str());
323 ::rename(backupFn.c_str(), fn.c_str());
324 status = 1;
325 continue;
328 // upgrade done
329 cout << "The following files have been upgraded\n"
330 << " " << fn.c_str() << "\n"
331 << "The previous version of the file has been renamed to\n"
332 << " " << backupFn.c_str() << endl;
335 return status;