Source code of Windows XP (NT5)
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.

1544 lines
42 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: mscdfapi.cpp
  8. //
  9. // Contents: Microsoft Internet Security Catalog Utilities
  10. //
  11. // Functions: CryptCATCDFOpen
  12. // CryptCATCDFClose
  13. // CryptCATCDFEnumMembers
  14. // CryptCATCDFEnumAttributes
  15. //
  16. // *** local functions ***
  17. //
  18. // CDFGetAttributes
  19. // CDFTextToGUID
  20. // CDFPositionAtGroupTag
  21. // CDFGetNextMember
  22. // CDFGetParam
  23. // CDFGetLine
  24. // CDFSplitAttrLine
  25. // CDFEOLOut
  26. // CDFCheckOID
  27. // CDFCalcIndirectData
  28. //
  29. // History: 01-May-1997 pberkman created
  30. //
  31. //--------------------------------------------------------------------------
  32. #include "global.hxx"
  33. #include <objbase.h>
  34. #include "mscat32.h"
  35. #include "sipguids.h"
  36. void CDFTextToGUID(LPWSTR pwszText, GUID *pgBin, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError);
  37. BOOL CDFPositionAtGroupTag(CRYPTCATCDF *pCDF, LPWSTR pwszTag);
  38. BOOL CDFPositionAtLastMember(CRYPTCATCDF *pCDF);
  39. BOOL CDFGetNextMember(CRYPTCATCDF *pCDF, LPWSTR pwszMember, LPWSTR pwszLastMember);
  40. BOOL CDFGetParam(CRYPTCATCDF *pCDF, LPWSTR pwszGroup, LPWSTR pwszItem,
  41. LPWSTR pwszDefault, LPWSTR *ppwszRet, LPWSTR pwszMemberTag);
  42. DWORD CDFGetLine(CRYPTCATCDF *pCDF, LPWSTR pwszLineBuf, DWORD dwMaxRead);
  43. BOOL CDFSplitAttrLine(LPWSTR pwszLine, DWORD *pdwType, LPWSTR *pwszOID,
  44. LPWSTR *pwszValue, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError);
  45. void CDFEOLOut(WCHAR *pwsz, DWORD ccLen);
  46. BOOL CDFCalcIndirectData(CRYPTCATCDF *pCDF, WCHAR *pwszFileName, GUID *pgSubjectType, DWORD *pcbIndirectData,
  47. BYTE **pIndirectData, DWORD *pdwCertVersion, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError);
  48. BOOL CDFCheckOID(LPWSTR pwszOID, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError);
  49. #define MAX_CDF_LINE_LEN 512
  50. #define CAT_HEADER_TAG L"[CatalogHeader]"
  51. #define CAT_HEADER_NAME_TAG L"Name"
  52. #define CAT_HEADER_RESDIR_TAG L"ResultDir"
  53. #define CAT_HEADER_VERSION_TAG L"PublicVersion"
  54. #define CAT_HEADER_ENCODETYPE_TAG L"EncodingType"
  55. #define CAT_HEADER_ATTR_TAG L"CATATTR"
  56. #define CAT_MEMBER_TAG L"[CatalogFiles]"
  57. #define CAT_MEMBER_ALTSIP_TAG L"ALTSIPID"
  58. #define CAT_MEMBER_ATTR_TAG L"ATTR"
  59. #define CAT_MEMBER_HASH_TAG L"<HASH>"
  60. /////////////////////////////////////////////////////////////////////////////
  61. //
  62. // Exported Functions
  63. //
  64. CRYPTCATCDF * WINAPI CryptCATCDFOpen(LPWSTR pwszFilePath,
  65. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  66. {
  67. CRYPTCATCDF *pCDF;
  68. HANDLE hFile;
  69. if (!(pwszFilePath))
  70. {
  71. SetLastError(ERROR_INVALID_PARAMETER);
  72. return(NULL);
  73. }
  74. if ((hFile = CreateFileU(pwszFilePath,
  75. GENERIC_READ,
  76. FILE_SHARE_READ,
  77. NULL,
  78. OPEN_EXISTING,
  79. FILE_ATTRIBUTE_NORMAL,
  80. NULL)) == INVALID_HANDLE_VALUE)
  81. {
  82. return(NULL);
  83. }
  84. if (!(pCDF = (CRYPTCATCDF *)CatalogNew(sizeof(CRYPTCATCDF))))
  85. {
  86. return(NULL);
  87. }
  88. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  89. LPWSTR pwsz;
  90. memset(pCDF, 0x00, sizeof(CRYPTCATCDF));
  91. pCDF->cbStruct = sizeof(CRYPTCATCDF);
  92. pCDF->hFile = hFile;
  93. //
  94. // Name
  95. //
  96. if (pwsz = wcsrchr(pwszFilePath, L'\\'))
  97. {
  98. wcscpy(&wszRetValue[0], &pwsz[1]);
  99. }
  100. else
  101. {
  102. wcscpy(&wszRetValue[0], pwszFilePath);
  103. }
  104. LPWSTR pwszStoreName;
  105. pwszStoreName = NULL;
  106. if (!(CDFPositionAtGroupTag(pCDF, CAT_HEADER_TAG)))
  107. {
  108. CloseHandle(hFile);
  109. delete pCDF;
  110. if (pfnParseError)
  111. {
  112. pfnParseError(CRYPTCAT_E_AREA_HEADER, CRYPTCAT_E_CDF_TAGNOTFOUND, CAT_HEADER_TAG);
  113. }
  114. return(NULL);
  115. }
  116. if (!(CDFGetParam(pCDF, CAT_HEADER_TAG, CAT_HEADER_NAME_TAG, &wszRetValue[0], &pwszStoreName, NULL)))
  117. {
  118. DELETE_OBJECT(pwszStoreName);
  119. CloseHandle(hFile);
  120. delete pCDF;
  121. if (pfnParseError)
  122. {
  123. pfnParseError(CRYPTCAT_E_AREA_HEADER, CRYPTCAT_E_CDF_TAGNOTFOUND, CAT_HEADER_TAG);
  124. }
  125. return(NULL);
  126. }
  127. //
  128. // ResultDir
  129. //
  130. CDFPositionAtGroupTag(pCDF, CAT_HEADER_TAG);
  131. CDFGetParam(pCDF, CAT_HEADER_TAG, CAT_HEADER_RESDIR_TAG, NULL, &pCDF->pwszResultDir, NULL);
  132. //
  133. // actual file
  134. //
  135. DWORD cw;
  136. LPWSTR pwszFile = NULL;
  137. cw = wcslen( pwszStoreName );
  138. if ( pCDF->pwszResultDir != NULL )
  139. {
  140. cw += wcslen( pCDF->pwszResultDir );
  141. }
  142. cw += wcslen( CRYPTCAT_FILEEXT );
  143. cw += 2;
  144. pwszFile = new WCHAR [ cw ];
  145. if ( pwszFile == NULL )
  146. {
  147. DELETE_OBJECT(pwszStoreName);
  148. CloseHandle(hFile);
  149. delete pCDF;
  150. return( NULL );
  151. }
  152. pwszFile[ 0 ] = L'\0';
  153. if (pCDF->pwszResultDir)
  154. {
  155. wcscpy(pwszFile, pCDF->pwszResultDir);
  156. if (pCDF->pwszResultDir[wcslen(pCDF->pwszResultDir) - 1] != L'\\')
  157. {
  158. wcscat(pwszFile, L"\\");
  159. }
  160. }
  161. wcscat(pwszFile, pwszStoreName);
  162. if (!(wcsrchr(pwszFile, '.')))
  163. {
  164. wcscat(pwszFile, L".");
  165. wcscat(pwszFile, CRYPTCAT_FILEEXT);
  166. }
  167. DWORD dwPublicVersion;
  168. DWORD dwEncodingType;
  169. //
  170. // PublicVersion
  171. //
  172. CDFPositionAtGroupTag(pCDF, CAT_HEADER_TAG);
  173. wcscpy(&wszRetValue[0], L"0x00000001");
  174. CDFGetParam(pCDF, CAT_HEADER_TAG, CAT_HEADER_VERSION_TAG, &wszRetValue[0], &pwsz, NULL);
  175. if (pwsz)
  176. {
  177. dwPublicVersion = wcstol(pwsz, NULL, 16);
  178. delete pwsz;
  179. }
  180. //
  181. // EncodingType
  182. //
  183. CDFPositionAtGroupTag(pCDF, CAT_HEADER_TAG);
  184. wcscpy(&wszRetValue[0], L"0x00010001"); // PKCS_7_ASN_ENCODING | X509_ASN_ENCODING
  185. CDFGetParam(pCDF, CAT_HEADER_TAG, CAT_HEADER_ENCODETYPE_TAG, &wszRetValue[0], &pwsz, NULL);
  186. if (pwsz)
  187. {
  188. dwEncodingType = wcstol(pwsz, NULL, 16);
  189. delete pwsz;
  190. }
  191. pCDF->hCATStore = CryptCATOpen(pwszFile, CRYPTCAT_OPEN_CREATENEW, NULL, dwPublicVersion, dwEncodingType);
  192. delete pwszStoreName;
  193. delete pwszFile;
  194. if ((pCDF->hCATStore == INVALID_HANDLE_VALUE) ||
  195. (!(pCDF->hCATStore)))
  196. {
  197. CryptCATCDFClose(pCDF);
  198. pCDF = NULL;
  199. }
  200. return(pCDF);
  201. }
  202. BOOL WINAPI CryptCATCDFClose(CRYPTCATCDF *pCDF)
  203. {
  204. BOOL fRet;
  205. if (!(pCDF) ||
  206. (pCDF->cbStruct != sizeof(CRYPTCATCDF)))
  207. {
  208. SetLastError(ERROR_INVALID_PARAMETER);
  209. return(FALSE);
  210. }
  211. fRet = TRUE;
  212. if ((pCDF->hFile) && (pCDF->hFile != INVALID_HANDLE_VALUE))
  213. {
  214. fRet &= CloseHandle(pCDF->hFile);
  215. }
  216. if ((pCDF->hCATStore) && (pCDF->hCATStore != INVALID_HANDLE_VALUE))
  217. {
  218. fRet &= CatalogSaveP7UData((CRYPTCATSTORE *)pCDF->hCATStore);
  219. fRet &= CryptCATClose(pCDF->hCATStore);
  220. }
  221. DELETE_OBJECT(pCDF->pwszResultDir);
  222. delete pCDF;
  223. return(fRet);
  224. }
  225. CRYPTCATATTRIBUTE * WINAPI CryptCATCDFEnumCatAttributes(CRYPTCATCDF *pCDF,
  226. CRYPTCATATTRIBUTE *pPrevAttr,
  227. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  228. {
  229. if (!(pCDF) ||
  230. (pCDF->cbStruct != sizeof(CRYPTCATCDF)))
  231. {
  232. SetLastError(ERROR_INVALID_PARAMETER);
  233. return(NULL);
  234. }
  235. LPWSTR pwsz;
  236. LPWSTR pwszOID;
  237. LPWSTR pwszValue;
  238. int iAttr;
  239. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  240. WCHAR wszTemp[64];
  241. DWORD dwType;
  242. CRYPTCATATTRIBUTE *pAttr;
  243. iAttr = (pPrevAttr) ? pPrevAttr->dwReserved + 1 : 1;
  244. wcscpy(&wszRetValue[0], CAT_HEADER_ATTR_TAG);
  245. wcscat(&wszRetValue[0], _itow(iAttr, &wszTemp[0], 10));
  246. pwsz = NULL;
  247. pAttr = NULL;
  248. CDFPositionAtGroupTag(pCDF, CAT_HEADER_TAG);
  249. if (CDFGetParam(pCDF, CAT_HEADER_TAG, &wszRetValue[0], NULL, &pwsz, NULL))
  250. {
  251. if (pwsz)
  252. {
  253. if (CDFSplitAttrLine(pwsz, &dwType, &pwszOID, &pwszValue, pfnParseError))
  254. {
  255. if (dwType & CRYPTCAT_ATTR_NAMEOBJID)
  256. {
  257. //
  258. // make sure we have a valid objid in the name.
  259. // we might do something better than this (???)
  260. //
  261. if (!(CDFCheckOID(pwszOID, pfnParseError)))
  262. {
  263. delete pwsz;
  264. return(NULL);
  265. }
  266. }
  267. if (dwType & CRYPTCAT_ATTR_UNAUTHENTICATED)
  268. {
  269. if (pfnParseError)
  270. {
  271. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_UNSUPPORTED, pwsz);
  272. }
  273. }
  274. else if (((dwType & CRYPTCAT_ATTR_NAMEOBJID) ||
  275. (dwType & CRYPTCAT_ATTR_NAMEASCII)) &&
  276. ((dwType & CRYPTCAT_ATTR_DATABASE64) ||
  277. (dwType & CRYPTCAT_ATTR_DATAASCII)))
  278. {
  279. pAttr = CryptCATPutCatAttrInfo(pCDF->hCATStore, pwszOID, dwType,
  280. (wcslen(pwszValue) + 1) * sizeof(WCHAR),
  281. (BYTE *)pwszValue);
  282. if (pAttr)
  283. {
  284. pAttr->dwReserved = iAttr;
  285. }
  286. }
  287. else
  288. {
  289. if (pfnParseError)
  290. {
  291. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TYPECOMBO,
  292. pwsz);
  293. }
  294. }
  295. }
  296. }
  297. }
  298. DELETE_OBJECT(pwsz);
  299. return(pAttr);
  300. }
  301. CRYPTCATMEMBER * WINAPI CryptCATCDFEnumMembers(CRYPTCATCDF *pCDF, CRYPTCATMEMBER *pPrevMember,
  302. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  303. {
  304. LPWSTR pwszLastTag;
  305. BOOL fFoundLastTag;
  306. pwszLastTag = NULL;
  307. if (pPrevMember)
  308. {
  309. if (pPrevMember->cbStruct != sizeof(CRYPTCATMEMBER))
  310. {
  311. SetLastError(ERROR_INVALID_PARAMETER);
  312. return(NULL);
  313. }
  314. if (pPrevMember->pwszReferenceTag)
  315. {
  316. if (!(pwszLastTag = (LPWSTR)CatalogNew(wcslen(pPrevMember->pwszReferenceTag) *
  317. sizeof(WCHAR) + 4)))
  318. {
  319. return(NULL);
  320. }
  321. wcscpy(pwszLastTag, pPrevMember->pwszReferenceTag);
  322. }
  323. }
  324. if (!(pCDF) ||
  325. (pCDF->hFile == INVALID_HANDLE_VALUE) ||
  326. !(pCDF->hFile))
  327. {
  328. DELETE_OBJECT(pwszLastTag);
  329. SetLastError(ERROR_INVALID_PARAMETER);
  330. return(NULL);
  331. }
  332. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  333. CDFPositionAtLastMember(pCDF);
  334. if (CDFGetNextMember(pCDF, &wszRetValue[0], pwszLastTag))
  335. {
  336. LPWSTR pwsz;
  337. DELETE_OBJECT(pwszLastTag);
  338. //
  339. // file path/name (required!)
  340. //
  341. CDFPositionAtLastMember(pCDF);
  342. if (!(CDFGetParam(pCDF, CAT_MEMBER_TAG, &wszRetValue[0], NULL, &pwsz, &wszRetValue[0])))
  343. {
  344. if (pfnParseError)
  345. {
  346. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_FILE_PATH,
  347. &wszRetValue[0]);
  348. }
  349. }
  350. else
  351. {
  352. CRYPTCATMEMBER *pMember;
  353. WCHAR *pwszFileName;
  354. WCHAR *pwszReferenceTag;
  355. GUID gSubjectType;
  356. HANDLE hFile;
  357. //
  358. // file path/name
  359. //
  360. pwszFileName = pwsz;
  361. // remember: don't delete pwsz this time!
  362. if ((hFile = CreateFileU(pwszFileName,
  363. GENERIC_READ,
  364. FILE_SHARE_READ,
  365. NULL,
  366. OPEN_EXISTING,
  367. FILE_ATTRIBUTE_NORMAL,
  368. NULL)) == INVALID_HANDLE_VALUE)
  369. {
  370. if (pfnParseError)
  371. {
  372. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_FILENOTFOUND,
  373. pwszFileName);
  374. }
  375. DELETE_OBJECT(pwszFileName);
  376. return(NULL);
  377. }
  378. CloseHandle(hFile);
  379. //
  380. // reference tag
  381. //
  382. if (!(pwszReferenceTag = (LPWSTR)CatalogNew((wcslen(&wszRetValue[0]) + 1) * sizeof(WCHAR))))
  383. {
  384. delete pwszFileName;
  385. return(NULL);
  386. }
  387. wcscpy(pwszReferenceTag, &wszRetValue[0]);
  388. //
  389. // Alt SIP GUID
  390. //
  391. wcscpy(&wszRetValue[0], pwszReferenceTag);
  392. wcscat(&wszRetValue[0], CAT_MEMBER_ALTSIP_TAG);
  393. CDFPositionAtLastMember(pCDF);
  394. CDFGetParam(pCDF, CAT_MEMBER_TAG, &wszRetValue[0], NULL, &pwsz, pwszReferenceTag);
  395. if (pwsz)
  396. {
  397. CDFTextToGUID(pwsz, &gSubjectType, pfnParseError);
  398. DELETE_OBJECT(pwszFileName);
  399. DELETE_OBJECT(pwsz);
  400. }
  401. else
  402. {
  403. if (!(CryptSIPRetrieveSubjectGuidForCatalogFile(pwszFileName, NULL, &gSubjectType)))
  404. {
  405. return(NULL);
  406. }
  407. }
  408. //
  409. // Indirect Data
  410. //
  411. BYTE *pbIndirectData;
  412. DWORD cbIndirectData;
  413. DWORD dwCertVersion;
  414. if (!(CDFCalcIndirectData(pCDF, pwszFileName, &gSubjectType, &cbIndirectData, &pbIndirectData,
  415. &dwCertVersion, pfnParseError)))
  416. {
  417. DELETE_OBJECT(pwszReferenceTag);
  418. DELETE_OBJECT(pwszFileName);
  419. return(NULL);
  420. }
  421. pMember = CryptCATPutMemberInfo(pCDF->hCATStore,
  422. pwszFileName,
  423. pwszReferenceTag,
  424. &gSubjectType,
  425. dwCertVersion,
  426. cbIndirectData,
  427. pbIndirectData);
  428. if (!(pMember) && (GetLastError() == CRYPT_E_EXISTS))
  429. {
  430. if (pfnParseError)
  431. {
  432. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_DUPLICATE,
  433. pwszReferenceTag);
  434. }
  435. }
  436. DELETE_OBJECT(pbIndirectData);
  437. //
  438. // Done!
  439. //
  440. DELETE_OBJECT(pwszReferenceTag);
  441. DELETE_OBJECT(pwszFileName);
  442. return(pMember);
  443. }
  444. }
  445. DELETE_OBJECT(pwszLastTag);
  446. return(NULL);
  447. }
  448. LPWSTR WINAPI CryptCATCDFEnumMembersByCDFTagEx(CRYPTCATCDF *pCDF, LPWSTR pwszPrevCDFTag,
  449. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError,
  450. CRYPTCATMEMBER** ppMember, BOOL fContinueOnError,
  451. LPVOID pvReserved)
  452. {
  453. LPWSTR pwszLastTag;
  454. BOOL fFoundLastTag;
  455. pwszLastTag = pwszPrevCDFTag;
  456. if (!(pCDF) ||
  457. (pCDF->hFile == INVALID_HANDLE_VALUE) ||
  458. !(pCDF->hFile))
  459. {
  460. DELETE_OBJECT(pwszLastTag);
  461. SetLastError(ERROR_INVALID_PARAMETER);
  462. return(NULL);
  463. }
  464. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  465. CDFPositionAtLastMember(pCDF);
  466. if (CDFGetNextMember(pCDF, &wszRetValue[0], pwszLastTag))
  467. {
  468. LPWSTR pwsz;
  469. DELETE_OBJECT(pwszLastTag);
  470. //
  471. // file path/name (required!)
  472. //
  473. CDFPositionAtLastMember(pCDF);
  474. if (!(CDFGetParam(pCDF, CAT_MEMBER_TAG, &wszRetValue[0], NULL, &pwsz, &wszRetValue[0])))
  475. {
  476. if (pfnParseError)
  477. {
  478. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_FILE_PATH,
  479. &wszRetValue[0]);
  480. }
  481. }
  482. else
  483. {
  484. CRYPTCATMEMBER *pMember;
  485. WCHAR *pwszFileName;
  486. WCHAR *pwszReferenceTag;
  487. GUID gSubjectType;
  488. HANDLE hFile;
  489. //
  490. // reference tag
  491. //
  492. if (!(pwszReferenceTag = (LPWSTR)CatalogNew((wcslen(&wszRetValue[0]) + 1) * sizeof(WCHAR))))
  493. {
  494. return(NULL);
  495. }
  496. wcscpy(pwszReferenceTag, &wszRetValue[0]);
  497. //
  498. // file path/name
  499. //
  500. pwszFileName = pwsz;
  501. // remember: don't delete pwsz this time!
  502. if ((hFile = CreateFileU(pwszFileName,
  503. GENERIC_READ,
  504. FILE_SHARE_READ,
  505. NULL,
  506. OPEN_EXISTING,
  507. FILE_ATTRIBUTE_NORMAL,
  508. NULL)) == INVALID_HANDLE_VALUE)
  509. {
  510. if (pfnParseError)
  511. {
  512. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_FILENOTFOUND,
  513. pwszFileName);
  514. }
  515. DELETE_OBJECT(pwszFileName);
  516. if ( fContinueOnError == FALSE )
  517. {
  518. DELETE_OBJECT(pwszReferenceTag);
  519. pwszReferenceTag = NULL;
  520. }
  521. return(pwszReferenceTag);
  522. }
  523. CloseHandle(hFile);
  524. //
  525. // Alt SIP GUID
  526. //
  527. wcscpy(&wszRetValue[0], pwszReferenceTag);
  528. wcscat(&wszRetValue[0], CAT_MEMBER_ALTSIP_TAG);
  529. CDFPositionAtLastMember(pCDF);
  530. CDFGetParam(pCDF, CAT_MEMBER_TAG, &wszRetValue[0], NULL, &pwsz, pwszReferenceTag);
  531. if (pwsz)
  532. {
  533. CDFTextToGUID(pwsz, &gSubjectType, pfnParseError);
  534. DELETE_OBJECT(pwszFileName);
  535. DELETE_OBJECT(pwsz);
  536. }
  537. else
  538. {
  539. if (!(CryptSIPRetrieveSubjectGuidForCatalogFile(pwszFileName, NULL, &gSubjectType)))
  540. {
  541. return(NULL);
  542. }
  543. }
  544. //
  545. // Indirect Data
  546. //
  547. BYTE *pbIndirectData;
  548. DWORD cbIndirectData;
  549. DWORD dwCertVersion;
  550. SIP_INDIRECT_DATA* pIndirectData;
  551. LPWSTR pwszTagToPut;
  552. BOOL fHashTagUsed = FALSE;
  553. if (!(CDFCalcIndirectData(pCDF, pwszFileName, &gSubjectType, &cbIndirectData, &pbIndirectData,
  554. &dwCertVersion, pfnParseError)))
  555. {
  556. DELETE_OBJECT(pwszFileName);
  557. if ( fContinueOnError == FALSE )
  558. {
  559. DELETE_OBJECT(pwszReferenceTag);
  560. pwszReferenceTag = NULL;
  561. }
  562. return(pwszReferenceTag);
  563. }
  564. pIndirectData = (SIP_INDIRECT_DATA *)pbIndirectData;
  565. pwszTagToPut = pwszReferenceTag;
  566. if (_wcsnicmp(pwszReferenceTag, CAT_MEMBER_HASH_TAG, wcslen(CAT_MEMBER_HASH_TAG)) == 0)
  567. {
  568. fHashTagUsed = TRUE;
  569. if (MsCatConstructHashTag(
  570. pIndirectData->Digest.cbData,
  571. pIndirectData->Digest.pbData,
  572. &pwszTagToPut
  573. ) == FALSE)
  574. {
  575. DELETE_OBJECT(pwszFileName);
  576. if ( fContinueOnError == FALSE )
  577. {
  578. DELETE_OBJECT(pwszReferenceTag);
  579. pwszReferenceTag = NULL;
  580. }
  581. return(pwszReferenceTag);
  582. }
  583. }
  584. pMember = CryptCATPutMemberInfo(pCDF->hCATStore,
  585. pwszFileName,
  586. pwszTagToPut,
  587. &gSubjectType,
  588. dwCertVersion,
  589. cbIndirectData,
  590. pbIndirectData);
  591. if (!(pMember) && (GetLastError() == CRYPT_E_EXISTS))
  592. {
  593. if (pfnParseError)
  594. {
  595. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_DUPLICATE,
  596. pwszReferenceTag);
  597. }
  598. }
  599. DELETE_OBJECT(pbIndirectData);
  600. //
  601. // Done!
  602. //
  603. if ( fHashTagUsed == TRUE )
  604. {
  605. MsCatFreeHashTag(pwszTagToPut);
  606. }
  607. DELETE_OBJECT(pwszFileName);
  608. *ppMember = pMember;
  609. return(pwszReferenceTag);
  610. }
  611. }
  612. DELETE_OBJECT(pwszLastTag);
  613. return(NULL);
  614. }
  615. LPWSTR WINAPI CryptCATCDFEnumMembersByCDFTag(CRYPTCATCDF *pCDF, LPWSTR pwszPrevCDFTag,
  616. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError,
  617. CRYPTCATMEMBER** ppMember)
  618. {
  619. return(CryptCATCDFEnumMembersByCDFTagEx(pCDF, pwszPrevCDFTag, pfnParseError, ppMember, FALSE, NULL));
  620. }
  621. BOOL CDFCalcIndirectData(CRYPTCATCDF *pCDF, WCHAR *pwszFileName, GUID *pgSubjectType, DWORD *pcbIndirectData,
  622. BYTE **ppbIndirectData, DWORD *pdwCertVersion, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  623. {
  624. SIP_SUBJECTINFO sSubjInfo;
  625. SIP_DISPATCH_INFO sSip;
  626. CRYPTCATSTORE *pCatStore;
  627. *pcbIndirectData = 0;
  628. *ppbIndirectData = NULL;
  629. pCatStore = (CRYPTCATSTORE *)pCDF->hCATStore;
  630. memset(&sSubjInfo, 0x00, sizeof(SIP_SUBJECTINFO));
  631. memset(&sSip, 0x00, sizeof(SIP_DISPATCH_INFO));
  632. sSubjInfo.cbSize = sizeof(SIP_SUBJECTINFO);
  633. sSubjInfo.hProv = pCatStore ->hProv;
  634. sSubjInfo.DigestAlgorithm.pszObjId = (char *)CertAlgIdToOID(CALG_SHA1);
  635. sSubjInfo.dwFlags = SPC_INC_PE_RESOURCES_FLAG | SPC_INC_PE_IMPORT_ADDR_TABLE_FLAG |
  636. MSSIP_FLAGS_PROHIBIT_RESIZE_ON_CREATE;
  637. sSubjInfo.dwEncodingType = pCatStore->dwEncodingType;
  638. sSubjInfo.pgSubjectType = pgSubjectType;
  639. sSubjInfo.pwsFileName = pwszFileName;
  640. if (!(CryptSIPLoad(pgSubjectType, 0, &sSip)))
  641. {
  642. if (pfnParseError)
  643. {
  644. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_INDIRECTDATA, pwszFileName);
  645. }
  646. return(FALSE);
  647. }
  648. sSip.pfCreate(&sSubjInfo,
  649. pcbIndirectData,
  650. NULL);
  651. if (*pcbIndirectData < 1)
  652. {
  653. if (pfnParseError)
  654. {
  655. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_INDIRECTDATA, pwszFileName);
  656. }
  657. return(FALSE);
  658. }
  659. if (!(*ppbIndirectData = (BYTE *)CatalogNew(*pcbIndirectData)))
  660. {
  661. *pcbIndirectData = 0;
  662. if (pfnParseError)
  663. {
  664. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_INDIRECTDATA, pwszFileName);
  665. }
  666. return(FALSE);
  667. }
  668. if (!(sSip.pfCreate(&sSubjInfo,
  669. pcbIndirectData,
  670. (SIP_INDIRECT_DATA *)*ppbIndirectData)))
  671. {
  672. DELETE_OBJECT(*ppbIndirectData);
  673. *pcbIndirectData = 0;
  674. if (pfnParseError)
  675. {
  676. pfnParseError(CRYPTCAT_E_AREA_MEMBER, CRYPTCAT_E_CDF_MEMBER_INDIRECTDATA, pwszFileName);
  677. }
  678. return(FALSE);
  679. }
  680. *pdwCertVersion = sSubjInfo.dwIntVersion;
  681. return(TRUE);
  682. }
  683. CRYPTCATATTRIBUTE * WINAPI CryptCATCDFEnumAttributes(CRYPTCATCDF *pCDF, CRYPTCATMEMBER *pMember,
  684. CRYPTCATATTRIBUTE *pPrevAttr,
  685. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  686. {
  687. if (!(pCDF) ||
  688. (pCDF->cbStruct != sizeof(CRYPTCATCDF)) ||
  689. !(pMember) ||
  690. (pMember->cbStruct != sizeof(CRYPTCATMEMBER)))
  691. {
  692. SetLastError(ERROR_INVALID_PARAMETER);
  693. return(NULL);
  694. }
  695. LPWSTR pwsz;
  696. LPWSTR pwszOID;
  697. LPWSTR pwszValue;
  698. int iAttr;
  699. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  700. WCHAR wszTemp[64];
  701. DWORD dwType;
  702. CRYPTCATATTRIBUTE *pAttr;
  703. iAttr = (pPrevAttr) ? pPrevAttr->dwReserved + 1 : 1;
  704. wcscpy(&wszRetValue[0], pMember->pwszReferenceTag);
  705. wcscat(&wszRetValue[0], L"ATTR");
  706. wcscat(&wszRetValue[0], _itow(iAttr, &wszTemp[0], 10));
  707. pwsz = NULL;
  708. pAttr = NULL;
  709. CDFPositionAtLastMember(pCDF);
  710. if (CDFGetParam(pCDF, CAT_MEMBER_TAG, &wszRetValue[0], NULL, &pwsz, pMember->pwszReferenceTag))
  711. {
  712. if (pwsz)
  713. {
  714. if (CDFSplitAttrLine(pwsz, &dwType, &pwszOID, &pwszValue, pfnParseError))
  715. {
  716. if (dwType & CRYPTCAT_ATTR_NAMEOBJID)
  717. {
  718. //
  719. // make sure we have a valid objid in the name.
  720. // we might do something better than this (???)
  721. //
  722. if (!(CDFCheckOID(pwszOID, pfnParseError)))
  723. {
  724. delete pwsz;
  725. return(NULL);
  726. }
  727. }
  728. if (dwType & CRYPTCAT_ATTR_UNAUTHENTICATED)
  729. {
  730. if (pfnParseError)
  731. {
  732. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_UNSUPPORTED, pwsz);
  733. }
  734. }
  735. else if (((dwType & CRYPTCAT_ATTR_NAMEOBJID) ||
  736. (dwType & CRYPTCAT_ATTR_NAMEASCII)) &&
  737. ((dwType & CRYPTCAT_ATTR_DATABASE64) ||
  738. (dwType & CRYPTCAT_ATTR_DATAASCII)))
  739. {
  740. pAttr = CryptCATPutAttrInfo(pCDF->hCATStore, pMember, pwszOID, dwType,
  741. (wcslen(pwszValue) + 1) * sizeof(WCHAR),
  742. (BYTE *)pwszValue);
  743. if (pAttr)
  744. {
  745. pAttr->dwReserved = iAttr;
  746. }
  747. }
  748. else
  749. {
  750. if (pfnParseError)
  751. {
  752. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TYPECOMBO,
  753. pwsz);
  754. }
  755. }
  756. }
  757. }
  758. }
  759. DELETE_OBJECT(pwsz);
  760. return(pAttr);
  761. }
  762. CRYPTCATATTRIBUTE * WINAPI CryptCATCDFEnumAttributesWithCDFTag(CRYPTCATCDF *pCDF, LPWSTR pwszMemberTag, CRYPTCATMEMBER *pMember,
  763. CRYPTCATATTRIBUTE *pPrevAttr,
  764. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  765. {
  766. if (!(pCDF) ||
  767. (pCDF->cbStruct != sizeof(CRYPTCATCDF)) ||
  768. !(pwszMemberTag) ||
  769. !(pMember) ||
  770. (pMember->cbStruct != sizeof(CRYPTCATMEMBER)))
  771. {
  772. SetLastError(ERROR_INVALID_PARAMETER);
  773. return(NULL);
  774. }
  775. LPWSTR pwsz;
  776. LPWSTR pwszOID;
  777. LPWSTR pwszValue;
  778. int iAttr;
  779. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  780. WCHAR wszTemp[64];
  781. DWORD dwType;
  782. CRYPTCATATTRIBUTE *pAttr;
  783. iAttr = (pPrevAttr) ? pPrevAttr->dwReserved + 1 : 1;
  784. wcscpy(&wszRetValue[0], pwszMemberTag);
  785. wcscat(&wszRetValue[0], L"ATTR");
  786. wcscat(&wszRetValue[0], _itow(iAttr, &wszTemp[0], 10));
  787. pwsz = NULL;
  788. pAttr = NULL;
  789. CDFPositionAtLastMember(pCDF);
  790. if (CDFGetParam(pCDF, CAT_MEMBER_TAG, &wszRetValue[0], NULL, &pwsz, pwszMemberTag))
  791. {
  792. if (pwsz)
  793. {
  794. if (CDFSplitAttrLine(pwsz, &dwType, &pwszOID, &pwszValue, pfnParseError))
  795. {
  796. if (dwType & CRYPTCAT_ATTR_NAMEOBJID)
  797. {
  798. //
  799. // make sure we have a valid objid in the name.
  800. // we might do something better than this (???)
  801. //
  802. if (!(CDFCheckOID(pwszOID, pfnParseError)))
  803. {
  804. delete pwsz;
  805. return(NULL);
  806. }
  807. }
  808. if (dwType & CRYPTCAT_ATTR_UNAUTHENTICATED)
  809. {
  810. if (pfnParseError)
  811. {
  812. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_UNSUPPORTED, pwsz);
  813. }
  814. }
  815. else if (((dwType & CRYPTCAT_ATTR_NAMEOBJID) ||
  816. (dwType & CRYPTCAT_ATTR_NAMEASCII)) &&
  817. ((dwType & CRYPTCAT_ATTR_DATABASE64) ||
  818. (dwType & CRYPTCAT_ATTR_DATAASCII)))
  819. {
  820. pAttr = CryptCATPutAttrInfo(pCDF->hCATStore, pMember, pwszOID, dwType,
  821. (wcslen(pwszValue) + 1) * sizeof(WCHAR),
  822. (BYTE *)pwszValue);
  823. if (pAttr)
  824. {
  825. pAttr->dwReserved = iAttr;
  826. }
  827. }
  828. else
  829. {
  830. if (pfnParseError)
  831. {
  832. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TYPECOMBO,
  833. pwsz);
  834. }
  835. }
  836. }
  837. }
  838. }
  839. DELETE_OBJECT(pwsz);
  840. return(pAttr);
  841. }
  842. /////////////////////////////////////////////////////////////////////////////
  843. //
  844. // Local Functions
  845. //
  846. BOOL CDFCheckOID(LPWSTR pwszOID, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  847. {
  848. DWORD cbConv;
  849. char *pszOID;
  850. cbConv = WideCharToMultiByte(0, 0,
  851. pwszOID, wcslen(pwszOID),
  852. NULL, 0, NULL, NULL);
  853. if (cbConv < 1)
  854. {
  855. if (pfnParseError)
  856. {
  857. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TYPECOMBO, pwszOID);
  858. }
  859. return(FALSE);
  860. }
  861. if (!(pszOID = (LPSTR)CatalogNew(cbConv)))
  862. {
  863. return(FALSE);
  864. }
  865. WideCharToMultiByte(0, 0,
  866. pwszOID, wcslen(pwszOID),
  867. pszOID, cbConv, NULL, NULL);
  868. DWORD i;
  869. BOOL fRet;
  870. fRet = TRUE;
  871. i = 0;
  872. while (i < cbConv)
  873. {
  874. if (((pszOID[i] < '0') || (pszOID[i] > '9')) &&
  875. (pszOID[i] != '.'))
  876. {
  877. fRet = FALSE;
  878. break;
  879. }
  880. i++;
  881. }
  882. delete pszOID;
  883. if (!(fRet))
  884. {
  885. if (pfnParseError)
  886. {
  887. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TYPECOMBO, pwszOID);
  888. }
  889. }
  890. return(fRet);
  891. }
  892. BOOL CDFSplitAttrLine(LPWSTR pwszLine, DWORD *pdwType, LPWSTR *ppwszOID, LPWSTR *ppwszValue,
  893. PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  894. {
  895. LPWSTR pwszColon;
  896. LPWSTR pwszStart;
  897. LPWSTR pwsz;
  898. *pdwType = 0;
  899. *ppwszValue = NULL;
  900. *ppwszOID = NULL;
  901. if (!(pwsz = (WCHAR *)CatalogNew((wcslen(pwszLine) + 1) * sizeof(WCHAR))))
  902. {
  903. return(FALSE);
  904. }
  905. wcscpy(pwsz, pwszLine);
  906. pwszStart = pwszLine;
  907. //
  908. // first one is type
  909. //
  910. if (!(pwszColon = wcschr(pwszStart, L':')))
  911. {
  912. if (pfnParseError)
  913. {
  914. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES, pwsz);
  915. }
  916. delete pwsz;
  917. return(FALSE);
  918. }
  919. *pwszColon = NULL;
  920. *pdwType = wcstol(pwszStart, NULL, 16);
  921. pwszStart = &pwszColon[1];
  922. //
  923. // next, oid/name
  924. //
  925. if (!(pwszColon = wcschr(pwszStart, L':')))
  926. {
  927. if (pfnParseError)
  928. {
  929. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES, pwsz);
  930. }
  931. delete pwsz;
  932. return(FALSE);
  933. }
  934. *pwszColon = NULL;
  935. *ppwszOID = pwszStart;
  936. pwszStart = &pwszColon[1];
  937. //
  938. // next, value
  939. //
  940. if (!(pwszStart[0]))
  941. {
  942. if (pfnParseError)
  943. {
  944. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES, pwsz);
  945. }
  946. delete pwsz;
  947. return(FALSE);
  948. }
  949. delete pwsz;
  950. *ppwszValue = pwszStart;
  951. return(TRUE);
  952. }
  953. void CDFTextToGUID(LPWSTR pwszText, GUID *pgBin, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError)
  954. {
  955. WCHAR wszGuid[256];
  956. GUID gTemp;
  957. memset(pgBin, 0x00, sizeof(GUID));
  958. if ((pwszText[0] != L'[') &&
  959. (pwszText[0] != L'{'))
  960. {
  961. wcscpy(&wszGuid[0], L"{");
  962. wcscat(&wszGuid[0], pwszText);
  963. wcscat(&wszGuid[0], L"}");
  964. }
  965. else
  966. {
  967. wcscpy(&wszGuid[0], pwszText);
  968. }
  969. if (!(wstr2guid(&wszGuid[0], pgBin)))
  970. {
  971. if (pfnParseError)
  972. {
  973. pfnParseError(CRYPTCAT_E_AREA_ATTRIBUTE, CRYPTCAT_E_CDF_BAD_GUID_CONV, &wszGuid[0]);
  974. }
  975. }
  976. }
  977. BOOL CDFPositionAtGroupTag(CRYPTCATCDF *pCDF, LPWSTR pwszTag)
  978. {
  979. if (SetFilePointer(pCDF->hFile, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF)
  980. {
  981. return(FALSE);
  982. }
  983. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  984. DWORD ccRet;
  985. while ((ccRet = CDFGetLine(pCDF, &wszRetValue[0], MAX_CDF_LINE_LEN * sizeof(WCHAR))) > 0)
  986. {
  987. if (wszRetValue[0] == L'#')
  988. {
  989. continue;
  990. }
  991. CDFEOLOut(&wszRetValue[0], ccRet);
  992. if (wszRetValue[0] == L'[')
  993. {
  994. if (_memicmp(&wszRetValue[0], pwszTag, wcslen(pwszTag) * sizeof(WCHAR)) == 0)
  995. {
  996. return(TRUE);
  997. }
  998. }
  999. }
  1000. return(FALSE);
  1001. }
  1002. BOOL CDFPositionAtLastMember(CRYPTCATCDF *pCDF)
  1003. {
  1004. if (pCDF->dwLastMemberOffset == 0)
  1005. {
  1006. return(CDFPositionAtGroupTag(pCDF, CAT_MEMBER_TAG));
  1007. }
  1008. else if (SetFilePointer(pCDF->hFile, pCDF->dwLastMemberOffset,
  1009. NULL, FILE_BEGIN) == 0xFFFFFFFF)
  1010. {
  1011. return(FALSE);
  1012. }
  1013. return(TRUE);
  1014. }
  1015. BOOL CDFGetNextMember(CRYPTCATCDF *pCDF, LPWSTR pwszMember, LPWSTR pwszLastMember)
  1016. {
  1017. WCHAR wszLine[MAX_CDF_LINE_LEN + 4];
  1018. WCHAR wszCheck[MAX_CDF_LINE_LEN + 1];
  1019. LPWSTR pwszEqual;
  1020. DWORD ccRet;
  1021. DWORD ccLastMember;
  1022. BOOL fFoundLast;
  1023. if (pwszLastMember)
  1024. {
  1025. wcscpy(&wszCheck[0], pwszLastMember);
  1026. ccLastMember = wcslen(&wszCheck[0]);
  1027. }
  1028. fFoundLast = FALSE;
  1029. while ((ccRet = CDFGetLine(pCDF, &wszLine[0], MAX_CDF_LINE_LEN * sizeof(WCHAR))) > 0)
  1030. {
  1031. if (wszLine[0] == L'#')
  1032. {
  1033. continue;
  1034. }
  1035. CDFEOLOut(&wszLine[0], ccRet);
  1036. if (wszLine[0] == L'[')
  1037. {
  1038. return(FALSE);
  1039. }
  1040. if (!(pwszEqual = wcschr(&wszLine[0], L'=')))
  1041. {
  1042. continue;
  1043. }
  1044. *pwszEqual = NULL;
  1045. if (pwszLastMember)
  1046. {
  1047. if (fFoundLast)
  1048. {
  1049. //
  1050. // before we make the determination that we are in fact on a
  1051. // different member tag, make sure that we aren't just on the
  1052. // same tag's ALTSIP or ATTRx!!!
  1053. //
  1054. wcscpy(&wszCheck[ccLastMember], CAT_MEMBER_ALTSIP_TAG);
  1055. if (_memicmp(&wszLine[0], &wszCheck[0], wcslen(&wszCheck[0]) * sizeof(WCHAR)) == 0)
  1056. {
  1057. continue;
  1058. }
  1059. wcscpy(&wszCheck[ccLastMember], CAT_MEMBER_ATTR_TAG);
  1060. if (_memicmp(&wszLine[0], &wszCheck[0], wcslen(&wszCheck[0]) * sizeof(WCHAR)) == 0)
  1061. {
  1062. continue;
  1063. }
  1064. if (_wcsicmp(&wszLine[0], pwszLastMember) != 0)
  1065. {
  1066. wcscpy(pwszMember, &wszLine[0]);
  1067. //
  1068. // remember the position of the last entry for this member
  1069. //
  1070. *pwszEqual = L'=';
  1071. pCDF->dwLastMemberOffset = pCDF->dwCurFilePos - wcslen(&wszLine[0]);
  1072. return(TRUE);
  1073. }
  1074. }
  1075. else if (_wcsicmp(&wszLine[0], pwszLastMember) == 0)
  1076. {
  1077. fFoundLast = TRUE;
  1078. }
  1079. continue;
  1080. }
  1081. wcscpy(pwszMember, &wszLine[0]);
  1082. //
  1083. // remember the position of the last entry for this member
  1084. //
  1085. *pwszEqual = L'=';
  1086. pCDF->dwLastMemberOffset = pCDF->dwCurFilePos - wcslen(&wszLine[0]);
  1087. return(TRUE);
  1088. }
  1089. return(FALSE);
  1090. }
  1091. BOOL CDFGetParam(CRYPTCATCDF *pCDF, LPWSTR pwszGroup, LPWSTR pwszItem, LPWSTR pwszDefault, LPWSTR *ppwszRet,
  1092. LPWSTR pwszMemberTag)
  1093. {
  1094. WCHAR wszRetValue[MAX_CDF_LINE_LEN + 4];
  1095. DWORD ccRet;
  1096. WCHAR *pwsz;
  1097. while ((ccRet = CDFGetLine(pCDF, &wszRetValue[0], MAX_CDF_LINE_LEN * sizeof(WCHAR))) > 0)
  1098. {
  1099. if (wszRetValue[0] == L'#')
  1100. {
  1101. continue;
  1102. }
  1103. CDFEOLOut(&wszRetValue[0], ccRet);
  1104. if (wszRetValue[0] == L'[')
  1105. {
  1106. break;
  1107. }
  1108. if (pwsz = wcschr(&wszRetValue[0], L'='))
  1109. {
  1110. //
  1111. // if we have a member tag and we are past it, get out!
  1112. //
  1113. if (pwszMemberTag)
  1114. {
  1115. if (_memicmp(&wszRetValue[0], pwszMemberTag, wcslen(pwszMemberTag) * sizeof(WCHAR)) != 0)
  1116. {
  1117. break;
  1118. }
  1119. }
  1120. *pwsz = NULL;
  1121. if (_memicmp(&wszRetValue[0], pwszItem, wcslen(pwszItem) * sizeof(WCHAR)) == 0)
  1122. {
  1123. if (wcslen(&pwsz[1]) < 1)
  1124. {
  1125. break;
  1126. }
  1127. if (*ppwszRet = (LPWSTR)CatalogNew((wcslen(&pwsz[1]) + 1) * sizeof(WCHAR)))
  1128. {
  1129. wcscpy(*ppwszRet, &pwsz[1]);
  1130. return(TRUE);
  1131. }
  1132. return(FALSE);
  1133. }
  1134. }
  1135. }
  1136. if (pwszDefault)
  1137. {
  1138. if (*ppwszRet = (LPWSTR)CatalogNew((wcslen(pwszDefault) + 1) * sizeof(WCHAR)))
  1139. {
  1140. wcscpy(*ppwszRet, pwszDefault);
  1141. return(TRUE);
  1142. }
  1143. }
  1144. *ppwszRet = NULL;
  1145. return(FALSE);
  1146. }
  1147. DWORD CDFGetLine(CRYPTCATCDF *pCDF, LPWSTR pwszLineBuf, DWORD cbMaxRead)
  1148. {
  1149. DWORD dwHold;
  1150. DWORD cbRead;
  1151. DWORD cwbRead;
  1152. DWORD dw;
  1153. int iAmt;
  1154. BYTE *pb;
  1155. if ((dwHold = SetFilePointer(pCDF->hFile, 0, NULL, FILE_CURRENT)) == 0xFFFFFFFF)
  1156. {
  1157. return(0);
  1158. }
  1159. if (!(pb = (BYTE *)CatalogNew(cbMaxRead + 2)))
  1160. {
  1161. return(0);
  1162. }
  1163. cbRead = 0;
  1164. if (ReadFile(pCDF->hFile, pb, cbMaxRead, &cbRead, NULL))
  1165. {
  1166. if (cbRead == 0)
  1167. {
  1168. pCDF->fEOF = TRUE;
  1169. delete pb;
  1170. return(0);
  1171. }
  1172. pb[cbRead] = 0x00;
  1173. pCDF->fEOF = FALSE;
  1174. if (cbRead > 0)
  1175. {
  1176. iAmt = 0;
  1177. for (dw = 0; dw < (cbRead - 1); dw++)
  1178. {
  1179. if ((pb[dw] == 0x0d) || (pb[dw] == 0x0a))
  1180. {
  1181. iAmt++;
  1182. if (pb[dw + 1] == 0x0a)
  1183. {
  1184. dw++;
  1185. iAmt++;
  1186. }
  1187. if (SetFilePointer(pCDF->hFile, dwHold + (dw + 1),
  1188. NULL, FILE_BEGIN) == 0xFFFFFFFF)
  1189. {
  1190. pCDF->dwCurFilePos = 0;
  1191. }
  1192. else
  1193. {
  1194. pCDF->dwCurFilePos = SetFilePointer(pCDF->hFile, 0, NULL, FILE_CURRENT) - iAmt;
  1195. }
  1196. pb[dw + 1] = 0x00;
  1197. cwbRead = MultiByteToWideChar(
  1198. CP_ACP,
  1199. 0,
  1200. (const char *)pb,
  1201. -1,
  1202. pwszLineBuf,
  1203. cbMaxRead / sizeof(WCHAR));
  1204. delete pb;
  1205. return(cwbRead + 1);
  1206. }
  1207. }
  1208. }
  1209. }
  1210. else
  1211. {
  1212. delete pb;
  1213. return(0);
  1214. }
  1215. if (pb[cbRead - 1] == 0x1a) /* EOF */
  1216. {
  1217. cbRead--;
  1218. pCDF->dwCurFilePos = 0;
  1219. pCDF->fEOF = TRUE;
  1220. }
  1221. else
  1222. {
  1223. pCDF->dwCurFilePos = dwHold;
  1224. }
  1225. pb[cbRead] = 0x00;
  1226. cwbRead = MultiByteToWideChar(
  1227. CP_ACP,
  1228. 0,
  1229. (const char *)pb,
  1230. -1,
  1231. pwszLineBuf,
  1232. cbMaxRead / sizeof(WCHAR));
  1233. delete pb;
  1234. return(cwbRead);
  1235. }
  1236. void CDFEOLOut(WCHAR *pwsz, DWORD ccLen)
  1237. {
  1238. DWORD i;
  1239. for (i = 0; i < ccLen; i++)
  1240. {
  1241. if ((pwsz[i] == (WCHAR)0x0a) || (pwsz[i] == (WCHAR)0x0d))
  1242. {
  1243. pwsz[i] = NULL;
  1244. return;
  1245. }
  1246. }
  1247. pwsz[ccLen] = NULL;
  1248. }