Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

504 lines
17 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. appc_cnv.c
  5. Abstract:
  6. Author:
  7. Calin Negreanu (calinn) 25-Mar-1999
  8. Revision History:
  9. <alias> <date> <comments>
  10. --*/
  11. #ifndef UNICODE
  12. #error UNICODE needs to be defined
  13. #else
  14. #define _UNICODE
  15. #endif
  16. #include <windows.h>
  17. #include <tchar.h>
  18. #include <winnt.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <setupapi.h>
  22. #include <badapps.h>
  23. BOOL CancelFlag = FALSE;
  24. BOOL *g_CancelFlagPtr = &CancelFlag;
  25. #ifdef DEBUG
  26. extern BOOL g_DoLog;
  27. #endif
  28. HANDLE g_hHeap;
  29. HINSTANCE g_hInst;
  30. BOOL g_UseInf = FALSE;
  31. PCTSTR g_DestInf = NULL;
  32. DWORD g_ValueSeq = 0;
  33. VOID
  34. HelpAndExit (
  35. VOID
  36. )
  37. {
  38. printf ("Command line syntax:\n\n"
  39. "tstbadap [-i:<inffile>]\n\n"
  40. "Optional Arguments:\n"
  41. " -i:<inffile> - Specifies INF file that will contain CheckBadApps data.\n"
  42. );
  43. exit(255);
  44. }
  45. BOOL
  46. DoesFileExistW(
  47. IN PCWSTR FileName,
  48. OUT PWIN32_FIND_DATAW FindData
  49. );
  50. BOOL
  51. pWorkerFn (
  52. VOID
  53. );
  54. INT
  55. __cdecl
  56. main (
  57. INT argc,
  58. CHAR *argv[]
  59. )
  60. {
  61. INT i;
  62. WCHAR destInf[MAX_PATH];
  63. #ifdef DEBUG
  64. g_DoLog = TRUE;
  65. #endif
  66. //
  67. // Parse command line
  68. //
  69. for (i = 1 ; i < argc ; i++) {
  70. if (argv[i][0] == '-' || argv[i][0] == '/') {
  71. switch (tolower (argv[i][1])) {
  72. case 'i':
  73. g_UseInf = TRUE;
  74. if (argv[i][2] == ':') {
  75. MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, &argv[i][3], -1, destInf, MAX_PATH);
  76. g_DestInf = destInf;
  77. } else if (i + 1 < argc) {
  78. i++;
  79. MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, argv[i], -1, destInf, MAX_PATH);
  80. g_DestInf = destInf;
  81. } else {
  82. HelpAndExit();
  83. }
  84. break;
  85. default:
  86. HelpAndExit();
  87. }
  88. } else {
  89. HelpAndExit();
  90. }
  91. }
  92. if ((g_UseInf) && (g_DestInf == NULL)) {
  93. HelpAndExit();
  94. }
  95. g_hHeap = GetProcessHeap();
  96. g_hInst = GetModuleHandle (NULL);
  97. pWorkerFn ();
  98. return 0;
  99. }
  100. PCWSTR
  101. GetFileNameFromPathW (
  102. IN PCWSTR PathSpec
  103. );
  104. #define S_CHECK_BAD_APPS TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\CheckBadApps")
  105. #define S_CHECK_BAD_APPS_400 TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\CheckBadApps400")
  106. #define S_APP_COMPATIBILITY TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\~AppCompatibility")
  107. BOOL
  108. OutputStrValue (
  109. IN PCTSTR VersionValue,
  110. OUT DWORD *Size,
  111. OUT PBYTE *Data
  112. )
  113. {
  114. PTSTR result;
  115. *Size = (_tcslen (VersionValue) + 1) * sizeof (TCHAR);
  116. result = HeapAlloc (g_hHeap, 0, *Size);
  117. if (!result) {
  118. return FALSE;
  119. }
  120. _tcscpy (result, VersionValue);
  121. *Data = (PBYTE)result;
  122. return TRUE;
  123. }
  124. typedef struct {
  125. ULONGLONG Value;
  126. ULONGLONG Mask;
  127. } BINVER_DATA, *PBINVER_DATA;
  128. BOOL
  129. OutputBinVerValue (
  130. IN PCTSTR VersionValue,
  131. OUT DWORD *Size,
  132. OUT PBYTE *Data
  133. )
  134. {
  135. PBINVER_DATA result;
  136. PWORD maskIdx;
  137. PWORD valueIdx;
  138. UINT index;
  139. result = HeapAlloc (g_hHeap, 0, sizeof (BINVER_DATA));
  140. if (!result) {
  141. return FALSE;
  142. }
  143. result->Value = 0;
  144. result->Mask = 0;
  145. *Size = sizeof (BINVER_DATA);
  146. maskIdx = (PWORD)&(result->Mask) + 3;
  147. valueIdx = (PWORD)&(result->Value) + 3;
  148. index = 0;
  149. while (VersionValue && *VersionValue) {
  150. *valueIdx = (WORD) _tcstoul ((PTSTR)VersionValue, &((PTSTR)VersionValue), 10);
  151. if (*VersionValue && (_tcsnextc (VersionValue) != TEXT('.'))) {
  152. return 0;
  153. }
  154. VersionValue = _tcsinc (VersionValue);
  155. *maskIdx = 0xFFFF;
  156. valueIdx --;
  157. maskIdx --;
  158. index ++;
  159. if (index >= 4) {
  160. break;
  161. }
  162. }
  163. *Data = (PBYTE)result;
  164. return TRUE;
  165. }
  166. BOOL
  167. OutputUpToBinVerValue (
  168. IN PCTSTR VersionValue,
  169. OUT DWORD *Size,
  170. OUT PBYTE *Data
  171. )
  172. {
  173. PULONGLONG result;
  174. PWORD valueIdx;
  175. UINT index;
  176. result = HeapAlloc (g_hHeap, 0, sizeof (ULONGLONG));
  177. if (!result) {
  178. return FALSE;
  179. }
  180. *result = 0;
  181. *Size = sizeof (ULONGLONG);
  182. valueIdx = (PWORD)result + 3;
  183. index = 0;
  184. while (VersionValue && *VersionValue) {
  185. *valueIdx = (WORD) _tcstoul ((PTSTR)VersionValue, &((PTSTR)VersionValue), 10);
  186. if (*VersionValue && (_tcsnextc (VersionValue) != TEXT('.'))) {
  187. return 0;
  188. }
  189. VersionValue = _tcsinc (VersionValue);
  190. valueIdx --;
  191. index ++;
  192. if (index >= 4) {
  193. break;
  194. }
  195. }
  196. *Data = (PBYTE)result;
  197. return TRUE;
  198. }
  199. VOID
  200. pPrintBadAppsData (
  201. PCTSTR BadAppsName,
  202. PCTSTR AddnlBadAppsName,
  203. PCTSTR KeyName,
  204. PCTSTR ValueName,
  205. DWORD MsgId,
  206. DWORD AppType,
  207. BOOL AppBinVer,
  208. PCTSTR AppBinVerData
  209. )
  210. {
  211. BYTE blob [8192];
  212. PBYTE blobPtr;
  213. BADAPP_PROP appProp;
  214. DWORD verId;
  215. PBYTE Data;
  216. DWORD DataSize;
  217. LONG status;
  218. HKEY addnlKey;
  219. HKEY exeKey;
  220. TCHAR valueName [MAX_PATH];
  221. blobPtr = blob;
  222. appProp.Size = sizeof (BADAPP_PROP);
  223. appProp.MsgId = MsgId;
  224. appProp.AppType = AppType;
  225. CopyMemory (blobPtr, &appProp, sizeof (BADAPP_PROP));
  226. blobPtr += sizeof (BADAPP_PROP);
  227. if (AppBinVer) {
  228. verId = VTID_UPTOBINPRODUCTVER;
  229. CopyMemory (blobPtr, &verId, sizeof (DWORD));
  230. blobPtr += sizeof (DWORD);
  231. OutputUpToBinVerValue (AppBinVerData, &DataSize, &Data);
  232. CopyMemory (blobPtr, &DataSize, sizeof (DWORD));
  233. blobPtr += sizeof (DWORD);
  234. CopyMemory (blobPtr, Data, DataSize);
  235. blobPtr += DataSize;
  236. HeapFree (g_hHeap, 0, Data);
  237. }
  238. verId = VTID_REQFILE;
  239. CopyMemory (blobPtr, &verId, sizeof (DWORD));
  240. blobPtr += sizeof (DWORD);
  241. OutputStrValue (ValueName, &DataSize, &Data);
  242. CopyMemory (blobPtr, &DataSize, sizeof (DWORD));
  243. blobPtr += sizeof (DWORD);
  244. CopyMemory (blobPtr, Data, DataSize);
  245. blobPtr += DataSize;
  246. HeapFree (g_hHeap, 0, Data);
  247. DataSize = 0;
  248. CopyMemory (blobPtr, &DataSize, sizeof (DWORD));
  249. blobPtr += sizeof (DWORD);
  250. if (g_UseInf) {
  251. } else {
  252. status = RegCreateKey (HKEY_LOCAL_MACHINE, AddnlBadAppsName, &addnlKey);
  253. if (status == ERROR_SUCCESS) {
  254. status = RegCreateKey (addnlKey, KeyName, &exeKey);
  255. if (status == ERROR_SUCCESS) {
  256. _itot (g_ValueSeq, valueName, 10);
  257. RegSetValueEx (exeKey, valueName, 0, REG_BINARY, blob, blobPtr - blob);
  258. }
  259. }
  260. }
  261. }
  262. BOOL
  263. pWorkerFn (
  264. VOID
  265. )
  266. {
  267. HKEY badAppKey = NULL;
  268. TCHAR exeKeyStr [MAX_PATH + 1];
  269. DWORD idxKey = 0;
  270. LONG statKey;
  271. HKEY exeKey = NULL;
  272. LONG status;
  273. DWORD index;
  274. TCHAR valueName [MAX_PATH];
  275. DWORD valueSize;
  276. DWORD valueType;
  277. DWORD blobSize;
  278. BYTE blobData[4096];
  279. DWORD msgId;
  280. DWORD appType;
  281. BOOL appBinVer;
  282. TCHAR appBinVerStr[MAX_PATH];
  283. TCHAR flagsValue [MAX_PATH];
  284. TCHAR binVerValue [MAX_PATH];
  285. BYTE addnlData[4096];
  286. PCTSTR flagsPtr;
  287. DWORD addnlSize;
  288. if (RegOpenKey (HKEY_LOCAL_MACHINE, S_CHECK_BAD_APPS, &badAppKey) == ERROR_SUCCESS) {
  289. idxKey = 0;
  290. statKey = ERROR_SUCCESS;
  291. while (statKey == ERROR_SUCCESS) {
  292. statKey = RegEnumKey (badAppKey, idxKey, exeKeyStr, MAX_PATH + 1);
  293. if (statKey == ERROR_SUCCESS) {
  294. if (RegOpenKey (badAppKey, exeKeyStr, &exeKey) == ERROR_SUCCESS) {
  295. index = 0;
  296. status = ERROR_SUCCESS;
  297. while (status == ERROR_SUCCESS) {
  298. blobSize = 4096;
  299. valueSize = MAX_PATH;
  300. status = RegEnumValue(exeKey, index, valueName, &valueSize, NULL, &valueType, blobData, &blobSize);
  301. if ((status == ERROR_SUCCESS) ||
  302. (status == ERROR_MORE_DATA)
  303. ) {
  304. if (valueType == REG_SZ) {
  305. msgId = 0;
  306. appType = 0;
  307. appBinVer = FALSE;
  308. msgId = _ttoi ((PCTSTR) blobData);
  309. if (msgId) {
  310. g_ValueSeq ++;
  311. _tcscpy (flagsValue, TEXT("Flags"));
  312. _tcscat (flagsValue, valueName);
  313. _tcscpy (binVerValue, TEXT("Version"));
  314. _tcscat (binVerValue, valueName);
  315. addnlSize = 4096;
  316. status = RegQueryValueEx (exeKey, flagsValue, NULL, &valueType, addnlData, &addnlSize);
  317. if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_SZ)) {
  318. flagsPtr = (PCTSTR) addnlData;
  319. while (*flagsPtr) {
  320. if (_tcsnextc (flagsPtr) == TEXT('Y')) {
  321. appType = appType | APPTYPE_INC_HARDBLOCK;
  322. }
  323. if (_tcsnextc (flagsPtr) == TEXT('L')) {
  324. appType = appType | APPTYPE_MINORPROBLEM;
  325. }
  326. if (_tcsnextc (flagsPtr) == TEXT('N')) {
  327. appType = appType | APPTYPE_FLAG_NONET;
  328. }
  329. if (_tcsnextc (flagsPtr) == TEXT('F')) {
  330. appType = appType | APPTYPE_FLAG_FAT32;
  331. }
  332. flagsPtr = _tcsinc (flagsPtr);
  333. }
  334. }
  335. if ((appType & APPTYPE_TYPE_MASK) == 0) {
  336. appType |= APPTYPE_INC_NOBLOCK;
  337. }
  338. addnlSize = 4096;
  339. status = RegQueryValueEx (exeKey, binVerValue, NULL, &valueType, addnlData, &addnlSize);
  340. if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_BINARY)) {
  341. PWORD valueIdx;
  342. appBinVer = TRUE;
  343. valueIdx = (PWORD) (addnlData);
  344. _stprintf (appBinVerStr, TEXT("%d.%d.%d.%d"), *(valueIdx + 1), *valueIdx, *(valueIdx + 3), *(valueIdx + 2));
  345. }
  346. pPrintBadAppsData (
  347. S_CHECK_BAD_APPS,
  348. S_APP_COMPATIBILITY,
  349. exeKeyStr,
  350. valueName,
  351. msgId,
  352. appType,
  353. appBinVer,
  354. appBinVerStr
  355. );
  356. status = ERROR_SUCCESS;
  357. }
  358. }
  359. }
  360. index ++;
  361. }
  362. }
  363. }
  364. idxKey ++;
  365. }
  366. }
  367. if (RegOpenKey (HKEY_LOCAL_MACHINE, S_CHECK_BAD_APPS_400, &badAppKey) == ERROR_SUCCESS) {
  368. idxKey = 0;
  369. statKey = ERROR_SUCCESS;
  370. while (statKey == ERROR_SUCCESS) {
  371. statKey = RegEnumKey (badAppKey, idxKey, exeKeyStr, MAX_PATH + 1);
  372. if (statKey == ERROR_SUCCESS) {
  373. if (RegOpenKey (badAppKey, exeKeyStr, &exeKey) == ERROR_SUCCESS) {
  374. index = 0;
  375. status = ERROR_SUCCESS;
  376. while (status == ERROR_SUCCESS) {
  377. blobSize = 4096;
  378. valueSize = MAX_PATH;
  379. status = RegEnumValue(exeKey, index, valueName, &valueSize, NULL, &valueType, blobData, &blobSize);
  380. if ((status == ERROR_SUCCESS) ||
  381. (status == ERROR_MORE_DATA)
  382. ) {
  383. if (valueType == REG_SZ) {
  384. msgId = 0;
  385. appType = 0;
  386. appBinVer = FALSE;
  387. msgId = _ttoi ((PCTSTR) blobData);
  388. if (msgId) {
  389. g_ValueSeq ++;
  390. _tcscpy (flagsValue, TEXT("Flags"));
  391. _tcscat (flagsValue, valueName);
  392. _tcscpy (binVerValue, TEXT("Version"));
  393. _tcscat (binVerValue, valueName);
  394. addnlSize = 4096;
  395. status = RegQueryValueEx (exeKey, flagsValue, NULL, &valueType, addnlData, &addnlSize);
  396. if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_SZ)) {
  397. flagsPtr = (PCTSTR) addnlData;
  398. while (*flagsPtr) {
  399. if (_tcsnextc (flagsPtr) == TEXT('Y')) {
  400. appType = appType | APPTYPE_INC_HARDBLOCK;
  401. }
  402. if (_tcsnextc (flagsPtr) == TEXT('L')) {
  403. appType = appType | APPTYPE_MINORPROBLEM;
  404. }
  405. if (_tcsnextc (flagsPtr) == TEXT('N')) {
  406. appType = appType | APPTYPE_FLAG_NONET;
  407. }
  408. if (_tcsnextc (flagsPtr) == TEXT('F')) {
  409. appType = appType | APPTYPE_FLAG_FAT32;
  410. }
  411. flagsPtr = _tcsinc (flagsPtr);
  412. }
  413. }
  414. if ((appType & APPTYPE_TYPE_MASK) == 0) {
  415. appType |= APPTYPE_INC_NOBLOCK;
  416. }
  417. addnlSize = 4096;
  418. status = RegQueryValueEx (exeKey, binVerValue, NULL, &valueType, addnlData, &addnlSize);
  419. if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_BINARY)) {
  420. PWORD valueIdx;
  421. appBinVer = TRUE;
  422. valueIdx = (PWORD) (addnlData);
  423. _stprintf (appBinVerStr, TEXT("%d.%d.%d.%d"), *(valueIdx + 1), *valueIdx, *(valueIdx + 3), *(valueIdx + 2));
  424. }
  425. pPrintBadAppsData (
  426. S_CHECK_BAD_APPS_400,
  427. S_APP_COMPATIBILITY,
  428. exeKeyStr,
  429. valueName,
  430. msgId,
  431. appType,
  432. appBinVer,
  433. appBinVerStr
  434. );
  435. status = ERROR_SUCCESS;
  436. }
  437. }
  438. }
  439. index ++;
  440. }
  441. }
  442. }
  443. idxKey ++;
  444. }
  445. }
  446. return TRUE;
  447. }