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.

502 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: makecat.cpp
  8. //
  9. // Contents: Microsoft Internet Security Catalog Utilities
  10. //
  11. // Functions: wmain
  12. //
  13. // History: 05-May-1997 pberkman created
  14. //
  15. //--------------------------------------------------------------------------
  16. #include <stdio.h>
  17. #include <windows.h>
  18. #include <io.h>
  19. #include <wchar.h>
  20. #include "unicode.h"
  21. #include "wincrypt.h"
  22. #include "wintrust.h"
  23. #include "mssip.h"
  24. #include "mscat.h"
  25. #include "dbgdef.h"
  26. #include "gendefs.h"
  27. #include "printfu.hxx"
  28. #include "cwargv.hxx"
  29. #include "resource.h"
  30. BOOL fVerbose = FALSE;
  31. BOOL fFailAllErrors = FALSE;
  32. BOOL fParseError = FALSE;
  33. BOOL fTesting = FALSE;
  34. DWORD dwExpectedError = 0;
  35. WCHAR *pwszCDFFile = NULL;
  36. PrintfU_ *pPrint = NULL;
  37. int iRet = 0;
  38. void WINAPI DisplayParseError(DWORD dwErrorArea, DWORD dwLocalError, WCHAR *wszName);
  39. extern "C" CRYPTCATATTRIBUTE * WINAPI CryptCATCDFEnumAttributesWithCDFTag(CRYPTCATCDF *pCDF, LPWSTR pwszMemberTag, CRYPTCATMEMBER *pMember,
  40. CRYPTCATATTRIBUTE *pPrevAttr,
  41. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError);
  42. extern "C" LPWSTR WINAPI CryptCATCDFEnumMembersByCDFTagEx(CRYPTCATCDF *pCDF, LPWSTR pwszPrevCDFTag,
  43. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError,
  44. CRYPTCATMEMBER** ppMember, BOOL fContinueOnError,
  45. LPVOID pvReserved);
  46. #define DEFAULT_STRING_BUFFER_SIZE 20
  47. char szDefaultBuffer[DEFAULT_STRING_BUFFER_SIZE];
  48. static LPSTR MakeMBSTR(LPWSTR pwsz, BOOL *pfAlloced)
  49. {
  50. int numChars = 0;
  51. LPSTR pszString = NULL;
  52. numChars = WideCharToMultiByte(0,
  53. 0,
  54. pwsz,
  55. -1,
  56. NULL,
  57. 0,
  58. NULL,
  59. NULL);
  60. if ((numChars + 1) > DEFAULT_STRING_BUFFER_SIZE)
  61. {
  62. pszString = new(char[numChars + 1]);
  63. WideCharToMultiByte(0,
  64. 0,
  65. pwsz,
  66. -1,
  67. pszString,
  68. numChars + 1,
  69. NULL,
  70. NULL);
  71. *pfAlloced = TRUE;
  72. return pszString;
  73. }
  74. else
  75. {
  76. WideCharToMultiByte(0,
  77. 0,
  78. pwsz,
  79. -1,
  80. szDefaultBuffer,
  81. numChars + 1,
  82. NULL,
  83. NULL);
  84. *pfAlloced = FALSE;
  85. return szDefaultBuffer;
  86. }
  87. }
  88. extern "C" int __cdecl wmain(int argc, WCHAR **wargv)
  89. {
  90. int cMember;
  91. cWArgv_ *pArgs;
  92. BOOL fFailed;
  93. CRYPTCATCDF *pCDF;
  94. CRYPTCATMEMBER *pMember;
  95. LPWSTR pwszMemberTag;
  96. CRYPTCATATTRIBUTE *pAttr;
  97. BOOL fContinueOnError;
  98. LPWSTR pwszOutputFile = NULL;
  99. HANDLE hOutputFile = INVALID_HANDLE_VALUE;
  100. HANDLE hFile = INVALID_HANDLE_VALUE;
  101. BOOL fAlloced;
  102. LPSTR psz;
  103. DWORD dwMinFileSize = 0;
  104. DWORD dwFileSize;
  105. BOOL fFileTooSmall = FALSE;
  106. DWORD dwBytesWritten;
  107. pCDF = NULL;
  108. if (!(pArgs = new cWArgv_((HINSTANCE)GetModuleHandle(NULL), &fFailed)))
  109. {
  110. goto MemoryError;
  111. }
  112. if (fFailed)
  113. {
  114. goto MemoryError;
  115. }
  116. pArgs->AddUsageText(IDS_USAGETEXT_USAGE, IDS_USAGETEXT_OPTIONS,
  117. IDS_USAGETEXT_CMDFILE, IDS_USAGETEXT_ADD,
  118. IDS_USAGETEXT_OPTPARAM);
  119. pArgs->Add2List(IDS_PARAM_HELP, IDS_PARAMTEXT_HELP, WARGV_VALUETYPE_BOOL, (void *)FALSE);
  120. pArgs->Add2List(IDS_PARAM_VERBOSE, IDS_PARAMTEXT_VERBOSE, WARGV_VALUETYPE_BOOL, (void *)FALSE);
  121. pArgs->Add2List(IDS_PARAM_FAILALWAYS, IDS_PARAMTEXT_FAILALWAYS, WARGV_VALUETYPE_BOOL, (void *)FALSE);
  122. pArgs->Add2List(IDS_PARAM_EXPERROR, IDS_PARAMTEXT_EXPERROR, WARGV_VALUETYPE_DWORDH, NULL, TRUE);
  123. pArgs->Add2List(IDS_PARAM_NOSTOPONERROR, IDS_PARAMTEXT_NOSTOPONERROR, WARGV_VALUETYPE_BOOL, (void *)FALSE);
  124. pArgs->Add2List(IDS_PARAM_MINSIZE, IDS_PARAMTEXT_MINSIZE, WARGV_VALUETYPE_DWORDD, (void *)0, FALSE);
  125. pArgs->Add2List(IDS_PARAM_OUTPUTFILE, IDS_PARAMTEXT_OUTPUTFILE, WARGV_VALUETYPE_WCHAR, NULL, FALSE);
  126. pArgs->Fill(argc, wargv);
  127. if (!(pArgs->Fill(argc, wargv)) ||
  128. (pArgs->GetValue(IDS_PARAM_HELP)))
  129. {
  130. wprintf(L"%s", pArgs->GetUsageString());
  131. goto NeededHelp;
  132. }
  133. fVerbose = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_VERBOSE));
  134. fFailAllErrors = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_FAILALWAYS));
  135. fContinueOnError = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_NOSTOPONERROR));
  136. if (pArgs->IsSet(IDS_PARAM_EXPERROR))
  137. {
  138. dwExpectedError = (DWORD)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_EXPERROR));
  139. fTesting = TRUE;
  140. }
  141. if (pArgs->IsSet(IDS_PARAM_MINSIZE))
  142. {
  143. dwMinFileSize = (DWORD)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_MINSIZE));
  144. }
  145. if (!(pwszCDFFile = pArgs->GetFileName()))
  146. {
  147. wprintf(L"%s", pArgs->GetUsageString());
  148. goto ParamError;
  149. }
  150. if (pArgs->IsSet(IDS_PARAM_OUTPUTFILE))
  151. {
  152. pwszOutputFile = (LPWSTR) pArgs->GetValue(IDS_PARAM_OUTPUTFILE);
  153. }
  154. pPrint = new PrintfU_;
  155. if (pPrint == NULL)
  156. {
  157. goto MemoryError;
  158. }
  159. SetLastError(0);
  160. if (!(pCDF = CryptCATCDFOpen(pwszCDFFile, DisplayParseError)))
  161. {
  162. if (fVerbose)
  163. {
  164. pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFOpen", GetLastError());
  165. }
  166. goto CDFOpenError;
  167. }
  168. if (fVerbose)
  169. {
  170. pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_OPENED), pwszCDFFile);
  171. }
  172. pAttr = NULL;
  173. while (pAttr = CryptCATCDFEnumCatAttributes(pCDF, pAttr, DisplayParseError))
  174. {
  175. if (fVerbose)
  176. {
  177. pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_ATTR),
  178. pAttr->pwszReferenceTag);
  179. }
  180. }
  181. //
  182. // If we are logging the the catalog members, then create the output file
  183. //
  184. if (pwszOutputFile != NULL)
  185. {
  186. hOutputFile = CreateFileU(
  187. pwszOutputFile,
  188. GENERIC_READ | GENERIC_WRITE,
  189. 0,
  190. NULL,
  191. CREATE_ALWAYS,
  192. FILE_ATTRIBUTE_NORMAL,
  193. NULL);
  194. if (hOutputFile == INVALID_HANDLE_VALUE)
  195. {
  196. printf("Error creating %S: %x", pwszOutputFile, GetLastError());
  197. goto ErrorReturn;
  198. }
  199. }
  200. pMember = NULL;
  201. pwszMemberTag = NULL;
  202. cMember = 0;
  203. while (pwszMemberTag = CryptCATCDFEnumMembersByCDFTagEx(pCDF, pwszMemberTag, DisplayParseError, &pMember, fContinueOnError, NULL))
  204. {
  205. //
  206. // Check for continuable error
  207. //
  208. if (GetLastError() != ERROR_SUCCESS)
  209. {
  210. if (fVerbose)
  211. {
  212. pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFEnumMembersByCDFTagEx", GetLastError());
  213. }
  214. if (fFailAllErrors)
  215. {
  216. iRet = 1;
  217. }
  218. continue;
  219. }
  220. //
  221. // Log to file
  222. //
  223. if (hOutputFile != INVALID_HANDLE_VALUE)
  224. {
  225. psz = MakeMBSTR(pMember->pwszFileName, &fAlloced);
  226. WriteFile(hOutputFile, psz, strlen(psz), &dwBytesWritten, NULL);
  227. if (fAlloced)
  228. {
  229. delete[]psz;
  230. }
  231. WriteFile(hOutputFile, " - ", 3, &dwBytesWritten, NULL);
  232. psz = MakeMBSTR(pMember->pwszReferenceTag, &fAlloced);
  233. WriteFile(hOutputFile, psz, strlen(psz), &dwBytesWritten, NULL);
  234. if (fAlloced)
  235. {
  236. delete[]psz;
  237. }
  238. WriteFile(hOutputFile, "\n", strlen("\n"), &dwBytesWritten, NULL);
  239. }
  240. //
  241. // If we are checking minimun file sizes:
  242. //
  243. if (dwMinFileSize > 0)
  244. {
  245. hFile = CreateFileU(pMember->pwszFileName,
  246. GENERIC_READ,
  247. FILE_SHARE_READ,
  248. NULL,
  249. OPEN_EXISTING,
  250. NULL,
  251. NULL);
  252. if (hFile != INVALID_HANDLE_VALUE)
  253. {
  254. dwFileSize = GetFileSize(hFile, NULL);
  255. // I assume that if this function fails, it is because the file
  256. // size won't fit into one DWORD. If it fails for some other
  257. // reason, a small file may slip through the cracks. Oh well.
  258. if ((dwFileSize < dwMinFileSize) &&
  259. (dwFileSize != INVALID_FILE_SIZE))
  260. {
  261. // The file is too small
  262. fFileTooSmall = TRUE;
  263. if (fVerbose)
  264. {
  265. pPrint->Display(IDS_STATUS_FMT,
  266. pPrint->get_String(IDS_STATUS_TOO_SMALL),
  267. pMember->pwszFileName);
  268. }
  269. }
  270. CloseHandle(hFile);
  271. }
  272. else
  273. {
  274. // Couldn't open file to check file size
  275. if (fVerbose)
  276. {
  277. pPrint->Display(IDS_ERROR_FUNCTION, L"CreateFile", GetLastError());
  278. }
  279. if (fFailAllErrors)
  280. {
  281. iRet = 1;
  282. }
  283. }
  284. }
  285. if (fVerbose)
  286. {
  287. pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_PROCESSED), pwszMemberTag);
  288. }
  289. cMember++;
  290. pAttr = NULL;
  291. while (pAttr = CryptCATCDFEnumAttributesWithCDFTag(pCDF, pwszMemberTag, pMember, pAttr, DisplayParseError))
  292. {
  293. if (fVerbose)
  294. {
  295. pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_ATTR),
  296. pAttr->pwszReferenceTag);
  297. }
  298. }
  299. }
  300. //
  301. // Check lasterror
  302. //
  303. if (GetLastError() != ERROR_SUCCESS)
  304. {
  305. if (fVerbose)
  306. {
  307. pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFEnumMembersByCDFTagEx", GetLastError());
  308. }
  309. iRet = 1;
  310. }
  311. //
  312. // Check for empty CDF
  313. //
  314. if ((fVerbose) && (cMember == 0))
  315. {
  316. pPrint->Display(IDS_ERROR_FUNCTION, pPrint->get_String(IDS_ERROR_NOMEMBERS), GetLastError());
  317. }
  318. //
  319. // Close the CAT file
  320. //
  321. if (!(CryptCATCDFClose(pCDF)))
  322. {
  323. if (fVerbose)
  324. {
  325. pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFClose", GetLastError());
  326. }
  327. if (fFailAllErrors)
  328. {
  329. goto CATCloseError;
  330. }
  331. }
  332. //
  333. // Done with main loop. The CAT file is created.
  334. //
  335. //
  336. // Check for expected errors from closing CAT file
  337. //
  338. if (fTesting)
  339. {
  340. pPrint->Display(IDS_FILEREF, pwszCDFFile);
  341. if (GetLastError() != dwExpectedError)
  342. {
  343. iRet = 1;
  344. pPrint->Display(IDS_EXPECTED_HRESULT, dwExpectedError, GetLastError());
  345. }
  346. else
  347. {
  348. iRet = 0;
  349. pPrint->Display(IDS_SUCCEEDED);
  350. }
  351. }
  352. //
  353. // Check for all standard success measurables
  354. //
  355. else if ((cMember > 0) && (!(fParseError)) && (!(fFileTooSmall)) && (iRet == 0))
  356. {
  357. pPrint->Display(IDS_SUCCEEDED);
  358. }
  359. else
  360. {
  361. if (fParseError)
  362. {
  363. pPrint->Display(IDS_ERROR_PARSE);
  364. }
  365. else if (fFileTooSmall)
  366. {
  367. pPrint->Display(IDS_ERROR_TOO_SMALL);
  368. }
  369. else
  370. {
  371. pPrint->Display(IDS_FAILED, GetLastError(), GetLastError());
  372. }
  373. iRet = 1;
  374. }
  375. if ((fFailAllErrors) && (cMember == 0) && !(fTesting))
  376. {
  377. iRet = 1;
  378. }
  379. CommonReturn:
  380. DELETE_OBJECT(pArgs);
  381. DELETE_OBJECT(pPrint);
  382. if (hOutputFile != INVALID_HANDLE_VALUE)
  383. {
  384. CloseHandle(hOutputFile);
  385. }
  386. return(iRet);
  387. ErrorReturn:
  388. iRet = 1;
  389. goto CommonReturn;
  390. TRACE_ERROR_EX(DBG_SS_APP, MemoryError);
  391. TRACE_ERROR_EX(DBG_SS_APP, ParamError);
  392. TRACE_ERROR_EX(DBG_SS_APP, NeededHelp);
  393. TRACE_ERROR_EX(DBG_SS_APP, CATCloseError);
  394. TRACE_ERROR_EX(DBG_SS_APP, CDFOpenError);
  395. }
  396. void WINAPI DisplayParseError(DWORD dwWhichArea, DWORD dwLocalError, WCHAR *pwszLine)
  397. {
  398. DWORD idErr;
  399. DWORD idFmt;
  400. fParseError = TRUE;
  401. switch (dwWhichArea)
  402. {
  403. case CRYPTCAT_E_AREA_HEADER: idFmt = IDS_PARSE_E_HEADER_FMT; break;
  404. case CRYPTCAT_E_AREA_MEMBER: idFmt = IDS_PARSE_E_MEMBER_FMT; break;
  405. case CRYPTCAT_E_AREA_ATTRIBUTE: idFmt = IDS_PARSE_E_ATTRIBUTE_FMT; break;
  406. default: idFmt = IDS_PARSE_E_ATTRIBUTE_FMT; break;
  407. }
  408. switch (dwLocalError)
  409. {
  410. case CRYPTCAT_E_CDF_MEMBER_FILE_PATH: idErr = IDS_PARSE_ERROR_FILE_PATH; break;
  411. case CRYPTCAT_E_CDF_MEMBER_INDIRECTDATA: idErr = IDS_PARSE_ERROR_INDIRECTDATA; break;
  412. case CRYPTCAT_E_CDF_MEMBER_FILENOTFOUND: idErr = IDS_PARSE_ERROR_FILENOTFOUND; break;
  413. case CRYPTCAT_E_CDF_BAD_GUID_CONV: idErr = IDS_PARSE_ERROR_GUID_CONV; break;
  414. case CRYPTCAT_E_CDF_ATTR_TYPECOMBO: idErr = IDS_PARSE_ERROR_TYPECOMBO; break;
  415. case CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES: idErr = IDS_PARSE_ERROR_TOOFEWVALUES; break;
  416. case CRYPTCAT_E_CDF_UNSUPPORTED: idErr = IDS_PARSE_ERROR_UNSUPPORTED; break;
  417. case CRYPTCAT_E_CDF_DUPLICATE: idErr = IDS_PARSE_ERROR_DUPLICATE; break;
  418. case CRYPTCAT_E_CDF_TAGNOTFOUND: idErr = IDS_PARSE_ERROR_NOTAG; break;
  419. default: idErr = IDS_PARSE_ERROR_UNKNOWN; break;
  420. }
  421. pPrint->Display(idFmt, pPrint->get_String(idErr), pwszLine);
  422. if (fFailAllErrors)
  423. {
  424. iRet = 1;
  425. }
  426. }