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.

863 lines
18 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. dbattrib.c
  5. Abstract:
  6. This source implements attribute functions used by MigDb
  7. Author:
  8. Calin Negreanu (calinn) 07-Jan-1998
  9. Revision History:
  10. 28-May-1999 ovidiut Added SECTIONKEY attribute
  11. 22-Apr-1999 jimschm Added UPTOBIN*VER attributes
  12. 07-Jan-1999 jimschm Added HASVERSION attribute
  13. 18-May-1998 jimschm Added INPARENTDIR attribute
  14. 08-Apr-1998 calinn Added two more attributes (ExeType and Description)
  15. 29-Jan-1998 calinn Modified CheckSum and FileSize to work with hex numbers
  16. 19-Jan-1998 calinn added CheckSum attribute
  17. --*/
  18. #include "pch.h"
  19. #include "logmsg.h"
  20. #include "osfiles.h"
  21. /*++
  22. Macro Expansion List Description:
  23. ATTRIBUTE_FUNCTIONS lists all valid attributes to query for a specific file.
  24. They are used by migdb in it's attempt to locate files.
  25. Line Syntax:
  26. DEFMAC(AttribFn, AttribName, ReqArgs)
  27. Arguments:
  28. AttribFn - This is a boolean function that returnes TRUE if a specified file has
  29. the specified attribute. You must implement a function with this name
  30. and required parameters.
  31. AttribName - This is the string that identifies the attribute function. It should
  32. have the same value as listed in migdb.inf
  33. ReqArgs - Specifies the number of args that are required for the action. Used
  34. by the parser.
  35. Variables Generated From List:
  36. g_AttributeFunctions - do not touch!
  37. For accessing the array there are the following functions:
  38. MigDb_GetAttributeAddr
  39. MigDb_GetAttributeIdx
  40. MigDb_GetAttributeName
  41. MigDb_GetReqArgCount
  42. --*/
  43. #define ATTRIBUTE_FUNCTIONS \
  44. DEFMAC(CompanyName, COMPANYNAME, 1) \
  45. DEFMAC(FileDescription, FILEDESCRIPTION, 1) \
  46. DEFMAC(FileVersion, FILEVERSION, 1) \
  47. DEFMAC(InternalName, INTERNALNAME, 1) \
  48. DEFMAC(LegalCopyright, LEGALCOPYRIGHT, 1) \
  49. DEFMAC(OriginalFilename, ORIGINALFILENAME, 1) \
  50. DEFMAC(ProductName, PRODUCTNAME, 1) \
  51. DEFMAC(ProductVersion, PRODUCTVERSION, 1) \
  52. DEFMAC(FileSize, FILESIZE, 1) \
  53. DEFMAC(IsMsBinary, ISMSBINARY, 0) \
  54. DEFMAC(CheckSum, CHECKSUM, 1) \
  55. DEFMAC(ExeType, EXETYPE, 1) \
  56. DEFMAC(Description, DESCRIPTION, 1) \
  57. DEFMAC(HasVersion, HASVERSION, 0) \
  58. DEFMAC(BinFileVer, BINFILEVER, 1) \
  59. DEFMAC(BinProductVer, BINPRODUCTVER, 1) \
  60. DEFMAC(FileDateHi, FILEDATEHI, 1) \
  61. DEFMAC(FileDateLo, FILEDATELO, 1) \
  62. DEFMAC(FileVerOs, FILEVEROS, 1) \
  63. DEFMAC(FileVerType, FILEVERTYPE, 1) \
  64. DEFMAC(SizeCheckSum, FC, 2) \
  65. DEFMAC(UpToBinProductVer, UPTOBINPRODUCTVER, 1) \
  66. DEFMAC(UpToBinFileVer, UPTOBINFILEVER, 1) \
  67. typedef struct {
  68. PCTSTR AttributeName;
  69. PATTRIBUTE_PROTOTYPE AttributeFunction;
  70. UINT RequiredArgs;
  71. } ATTRIBUTE_STRUCT, *PATTRIBUTE_STRUCT;
  72. //
  73. // Declare the attribute functions
  74. //
  75. #define DEFMAC(fn,id,reqargs) ATTRIBUTE_PROTOTYPE fn;
  76. ATTRIBUTE_FUNCTIONS
  77. #undef DEFMAC
  78. //
  79. // Declare a global array of functions and name identifiers for attribute functions
  80. //
  81. #define DEFMAC(fn,id,regargs) {TEXT(#id), fn, regargs},
  82. static ATTRIBUTE_STRUCT g_AttributeFunctions[] = {
  83. ATTRIBUTE_FUNCTIONS
  84. {NULL, NULL}
  85. };
  86. #undef DEFMAC
  87. BOOL
  88. pAlwaysFalseAttribute (
  89. IN PDBATTRIB_PARAMS AttribParams,
  90. IN PCTSTR Args
  91. )
  92. {
  93. return FALSE;
  94. }
  95. PATTRIBUTE_PROTOTYPE
  96. MigDb_GetAttributeAddr (
  97. IN INT AttributeIdx
  98. )
  99. /*++
  100. Routine Description:
  101. MigDb_GetAttributeAddr returns the address of the attribute function based on the attribute index
  102. Arguments:
  103. AttributeIdx - Attribute index.
  104. Return value:
  105. Attribute function address. Note that no checking is made so the address returned could be invalid.
  106. This is not a problem since the parsing code did the right job.
  107. --*/
  108. {
  109. if (AttributeIdx == -1) {
  110. return &pAlwaysFalseAttribute;
  111. }
  112. return g_AttributeFunctions[AttributeIdx].AttributeFunction;
  113. }
  114. INT
  115. MigDb_GetAttributeIdx (
  116. IN PCTSTR AttributeName
  117. )
  118. /*++
  119. Routine Description:
  120. MigDb_GetAttributeIdx returns the attribute index based on the attribute name
  121. Arguments:
  122. AttributeName - Attribute name.
  123. Return value:
  124. Attribute index. If the name is not found, the index returned is -1.
  125. --*/
  126. {
  127. PATTRIBUTE_STRUCT p = g_AttributeFunctions;
  128. INT i = 0;
  129. while (p->AttributeName != NULL) {
  130. if (StringIMatch (p->AttributeName, AttributeName)) {
  131. return i;
  132. }
  133. p++;
  134. i++;
  135. }
  136. return -1;
  137. }
  138. PCTSTR
  139. MigDb_GetAttributeName (
  140. IN INT AttributeIdx
  141. )
  142. /*++
  143. Routine Description:
  144. MigDb_GetAttributeName returns the name of an attribute based on the attribute index
  145. Arguments:
  146. AttributeIdx - Attribute index.
  147. Return value:
  148. Attribute name. Note that no checking is made so the returned pointer could be invalid.
  149. This is not a problem since the parsing code did the right job.
  150. --*/
  151. {
  152. if (AttributeIdx == -1) {
  153. return TEXT("nul");
  154. }
  155. return g_AttributeFunctions[AttributeIdx].AttributeName;
  156. }
  157. UINT
  158. MigDb_GetReqArgCount (
  159. IN INT AttributeIndex
  160. )
  161. /*++
  162. Routine Description:
  163. MigDb_GetReqArgCount is called by the migdb parser to get the required
  164. argument count. When the parser sees arguments that lack the required
  165. arguments, it skips them.
  166. Arguments:
  167. Index - Specifies the argument index
  168. Return Value:
  169. The required argument count, which can be zero or more.
  170. --*/
  171. {
  172. if (AttributeIndex == -1) {
  173. return 0;
  174. }
  175. return g_AttributeFunctions[AttributeIndex].RequiredArgs;
  176. }
  177. ULONGLONG
  178. GetBinFileVer (
  179. IN PCTSTR FileName
  180. )
  181. {
  182. VRVALUE_ENUM Version;
  183. ULONGLONG result = 0;
  184. if (VrCreateEnumStruct (&Version, FileName)) {
  185. result = VrGetBinaryFileVersion (&Version);
  186. VrDestroyEnumStruct (&Version);
  187. }
  188. return result;
  189. }
  190. ULONGLONG
  191. GetBinProductVer (
  192. IN PCTSTR FileName
  193. )
  194. {
  195. VRVALUE_ENUM Version;
  196. ULONGLONG result = 0;
  197. if (VrCreateEnumStruct (&Version, FileName)) {
  198. result = VrGetBinaryProductVersion (&Version);
  199. VrDestroyEnumStruct (&Version);
  200. }
  201. return result;
  202. }
  203. DWORD
  204. GetFileDateHi (
  205. IN PCTSTR FileName
  206. )
  207. {
  208. VRVALUE_ENUM Version;
  209. DWORD result = 0;
  210. if (VrCreateEnumStruct (&Version, FileName)) {
  211. result = VrGetBinaryFileDateHi (&Version);
  212. VrDestroyEnumStruct (&Version);
  213. }
  214. return result;
  215. }
  216. DWORD
  217. GetFileDateLo (
  218. IN PCTSTR FileName
  219. )
  220. {
  221. VRVALUE_ENUM Version;
  222. DWORD result = 0;
  223. if (VrCreateEnumStruct (&Version, FileName)) {
  224. result = VrGetBinaryFileDateLo (&Version);
  225. VrDestroyEnumStruct (&Version);
  226. }
  227. return result;
  228. }
  229. DWORD
  230. GetFileVerOs (
  231. IN PCTSTR FileName
  232. )
  233. {
  234. VRVALUE_ENUM Version;
  235. DWORD result = 0;
  236. if (VrCreateEnumStruct (&Version, FileName)) {
  237. result = VrGetBinaryOsVersion (&Version);
  238. VrDestroyEnumStruct (&Version);
  239. }
  240. return result;
  241. }
  242. DWORD
  243. GetFileVerType (
  244. IN PCTSTR FileName
  245. )
  246. {
  247. VRVALUE_ENUM Version;
  248. DWORD result = 0;
  249. if (VrCreateEnumStruct (&Version, FileName)) {
  250. result = VrGetBinaryFileType (&Version);
  251. VrDestroyEnumStruct (&Version);
  252. }
  253. return result;
  254. }
  255. /*++
  256. CompanyName, FileDescription, FileVersion, InternalName, LegalCopyright, OriginalFilename,
  257. ProductName, ProductVersion are attribute functions that are querying the version structure
  258. for their specific entries. They all return TRUE if the specific entry has specific value,
  259. FALSE otherwise.
  260. --*/
  261. BOOL
  262. CompanyName (
  263. IN PDBATTRIB_PARAMS AttribParams,
  264. IN PCTSTR Args
  265. )
  266. {
  267. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("CompanyName"), Args);
  268. }
  269. BOOL
  270. FileDescription (
  271. IN PDBATTRIB_PARAMS AttribParams,
  272. IN PCTSTR Args
  273. )
  274. {
  275. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("FileDescription"), Args);
  276. }
  277. BOOL
  278. FileVersion (
  279. IN PDBATTRIB_PARAMS AttribParams,
  280. IN PCTSTR Args
  281. )
  282. {
  283. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("FileVersion"), Args);
  284. }
  285. BOOL
  286. InternalName (
  287. IN PDBATTRIB_PARAMS AttribParams,
  288. IN PCTSTR Args
  289. )
  290. {
  291. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("InternalName"), Args);
  292. }
  293. BOOL
  294. LegalCopyright (
  295. IN PDBATTRIB_PARAMS AttribParams,
  296. IN PCTSTR Args
  297. )
  298. {
  299. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("LegalCopyright"), Args);
  300. }
  301. BOOL
  302. OriginalFilename (
  303. IN PDBATTRIB_PARAMS AttribParams,
  304. IN PCTSTR Args
  305. )
  306. {
  307. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("OriginalFilename"), Args);
  308. }
  309. BOOL
  310. ProductName (
  311. IN PDBATTRIB_PARAMS AttribParams,
  312. IN PCTSTR Args
  313. )
  314. {
  315. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("ProductName"), Args);
  316. }
  317. BOOL
  318. ProductVersion (
  319. IN PDBATTRIB_PARAMS AttribParams,
  320. IN PCTSTR Args
  321. )
  322. {
  323. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("ProductVersion"), Args);
  324. }
  325. BOOL
  326. FileSize (
  327. IN PDBATTRIB_PARAMS AttribParams,
  328. IN PCTSTR Args
  329. )
  330. /*++
  331. Routine Description:
  332. FileSize checks for the size of a file.
  333. Arguments:
  334. Params - See definition.
  335. Args - MultiSz. First Sz is the file size we need to check.
  336. Return value:
  337. TRUE - the file size matches Args
  338. FALSE - otherwise
  339. --*/
  340. {
  341. DWORD fileSize;
  342. _stscanf (Args, TEXT("%lx"), &fileSize);
  343. if (fileSize == AttribParams->FileParams->FindData->nFileSizeLow) {
  344. return TRUE;
  345. }
  346. else {
  347. return (_ttoi64 (Args) == AttribParams->FileParams->FindData->nFileSizeLow);
  348. }
  349. }
  350. BOOL
  351. IsMsBinary (
  352. IN PDBATTRIB_PARAMS AttribParams,
  353. IN PCTSTR Args
  354. )
  355. /*++
  356. Routine Description:
  357. IsMsBinary checks to see if a certain file is Microsoft stuff. For 32 bit modules
  358. we query CompanyName for "Microsoft" somewhere inside. For other modules we are
  359. relying on InWinDir attribute
  360. Arguments:
  361. Params - See definition.
  362. Args - MultiSz. Not used.
  363. Return value:
  364. TRUE - the file is MS stuff
  365. FALSE - otherwise
  366. --*/
  367. {
  368. return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("CompanyName"), TEXT("*Microsoft*"));
  369. }
  370. BOOL
  371. CheckSum (
  372. PDBATTRIB_PARAMS AttribParams,
  373. IN PCTSTR Args
  374. )
  375. /*++
  376. Routine Description:
  377. CheckSum returns TRUE if file's checksum equals the value in Args
  378. Arguments:
  379. Params - See definition.
  380. Args - checksum value.
  381. Return value:
  382. TRUE - the file's checksum equals the value in Args
  383. FALSE - otherwise
  384. --*/
  385. {
  386. UINT checkSum = 0;
  387. UINT oldSum = 0;
  388. checkSum = MdGetCheckSum (AttribParams->FileParams->NativeObjectName);
  389. _stscanf (Args, TEXT("%lx"), &oldSum);
  390. if (oldSum == checkSum) {
  391. return TRUE;
  392. }
  393. else {
  394. return (_ttoi64 (Args) == checkSum);
  395. }
  396. }
  397. BOOL
  398. SizeCheckSum (
  399. PDBATTRIB_PARAMS AttribParams,
  400. IN PCTSTR Args
  401. )
  402. /*++
  403. Routine Description:
  404. Returns TRUE if file's size equals first arg and checksum equals to the second arg
  405. Arguments:
  406. Params - See definition.
  407. Args - checksum value.
  408. Return value:
  409. TRUE - the file's checksum equals the value in Args
  410. FALSE - otherwise
  411. --*/
  412. {
  413. PCTSTR currArg = Args;
  414. if (!FileSize (AttribParams, currArg)) {
  415. return FALSE;
  416. }
  417. currArg = GetEndOfString (currArg);
  418. if (!currArg) {
  419. return FALSE;
  420. }
  421. currArg = _tcsinc (currArg);
  422. if (!currArg) {
  423. return FALSE;
  424. }
  425. return (CheckSum (AttribParams, currArg));
  426. }
  427. PTSTR g_ExeTypes[] = {
  428. TEXT("NONE"),
  429. TEXT("DOS"),
  430. TEXT("WIN16"),
  431. TEXT("WIN32")
  432. };
  433. BOOL
  434. ExeType (
  435. PDBATTRIB_PARAMS AttribParams,
  436. IN PCTSTR Args
  437. )
  438. /*++
  439. Routine Description:
  440. ExeType returns TRUE if file's type is according with Args. This can be:
  441. NONE, DOS, WIN16, WIN32
  442. Arguments:
  443. Params - See definition.
  444. Args - type of module.
  445. Return value:
  446. TRUE - the file's type is the same as Args
  447. FALSE - otherwise
  448. --*/
  449. {
  450. return IsPatternMatch (Args, g_ExeTypes[MdGetModuleType (AttribParams->FileParams->NativeObjectName)]);
  451. }
  452. BOOL
  453. Description (
  454. PDBATTRIB_PARAMS AttribParams,
  455. IN PCTSTR Args
  456. )
  457. /*++
  458. Routine Description:
  459. Description returns TRUE if file's description matches Args
  460. Arguments:
  461. Params - See definition.
  462. Args - description
  463. Return value:
  464. TRUE - the file's description matches Args
  465. FALSE - otherwise
  466. --*/
  467. {
  468. PCTSTR descr = NULL;
  469. BOOL result = FALSE;
  470. descr = MdGet16ModuleDescription (AttribParams->FileParams->NativeObjectName);
  471. if (descr != NULL) {
  472. result = IsPatternMatch (Args, descr);
  473. FreePathString (descr);
  474. }
  475. return result;
  476. }
  477. BOOL
  478. HasVersion (
  479. IN PDBATTRIB_PARAMS AttribParams,
  480. IN PCTSTR Args
  481. )
  482. /*++
  483. Routine Description:
  484. HasVersion determines if a file has any entries in its version
  485. stamp.
  486. Arguments:
  487. Params - Specifies the helper params that give the files to test.
  488. Args - Unused
  489. Return Value:
  490. TRUE if the specified file has an entry in its version stamp,
  491. FALSE otherwsie.
  492. --*/
  493. {
  494. VRVALUE_ENUM Version;
  495. BOOL Result = FALSE;
  496. if (VrCreateEnumStruct (&Version, AttribParams->FileParams->NativeObjectName)) {
  497. Result = TRUE;
  498. VrDestroyEnumStruct (&Version);
  499. }
  500. return Result;
  501. }
  502. BOOL
  503. pHexMatch (
  504. IN DWORD NewValue,
  505. IN PCTSTR Args
  506. )
  507. {
  508. DWORD oldValue;
  509. _stscanf (Args, TEXT("%lx"), &oldValue);
  510. if (oldValue == NewValue) {
  511. return TRUE;
  512. }
  513. else {
  514. return (_ttoi64 (Args) == NewValue);
  515. }
  516. }
  517. BOOL
  518. pConvertDotStringToValue (
  519. IN PCTSTR String,
  520. OUT ULONGLONG *Value
  521. )
  522. {
  523. PWORD valueIdx;
  524. UINT index;
  525. valueIdx = (PWORD) Value + 3;
  526. for (index = 0 ; index < 4 ; index++) {
  527. if (*String == 0) {
  528. *valueIdx = 0xFFFF;
  529. valueIdx--;
  530. continue;
  531. }
  532. *valueIdx = (WORD) _tcstoul (String, &(PTSTR) String, 10);
  533. if (*String && (_tcsnextc (String) != TEXT('.'))) {
  534. return FALSE;
  535. }
  536. String = _tcsinc (String);
  537. valueIdx--;
  538. }
  539. return TRUE;
  540. }
  541. BOOL
  542. pMaskHexMatch (
  543. IN ULONGLONG NewValue,
  544. IN PCTSTR Args
  545. )
  546. {
  547. ULONGLONG oldValue = 0;
  548. ULONGLONG mask = 0;
  549. PWORD maskIdx;
  550. PWORD valueIdx;
  551. UINT index;
  552. maskIdx = (PWORD)&mask + 3;
  553. valueIdx = (PWORD)&oldValue + 3;
  554. index = 0;
  555. while (Args && *Args) {
  556. if (index >= 4) {
  557. return FALSE;
  558. }
  559. *valueIdx = (WORD) _tcstoul ((PTSTR)Args, &((PTSTR)Args), 10);
  560. if (*Args) {
  561. if (_tcsnextc (Args) != TEXT('.')) {
  562. return FALSE;
  563. }
  564. Args = _tcsinc (Args);
  565. }
  566. *maskIdx = 65535;
  567. valueIdx--;
  568. maskIdx--;
  569. index++;
  570. }
  571. NewValue = NewValue & mask;
  572. return (oldValue == NewValue);
  573. }
  574. BOOL
  575. BinFileVer (
  576. IN PDBATTRIB_PARAMS AttribParams,
  577. IN PCTSTR Args
  578. )
  579. {
  580. return pMaskHexMatch (GetBinFileVer (AttribParams->FileParams->NativeObjectName), Args);
  581. }
  582. BOOL
  583. BinProductVer (
  584. IN PDBATTRIB_PARAMS AttribParams,
  585. IN PCTSTR Args
  586. )
  587. {
  588. return pMaskHexMatch (GetBinProductVer (AttribParams->FileParams->NativeObjectName), Args);
  589. }
  590. BOOL
  591. FileDateHi (
  592. IN PDBATTRIB_PARAMS AttribParams,
  593. IN PCTSTR Args
  594. )
  595. {
  596. return pHexMatch (GetFileDateHi (AttribParams->FileParams->NativeObjectName), Args);
  597. }
  598. BOOL
  599. FileDateLo (
  600. IN PDBATTRIB_PARAMS AttribParams,
  601. IN PCTSTR Args
  602. )
  603. {
  604. return pHexMatch (GetFileDateLo (AttribParams->FileParams->NativeObjectName), Args);
  605. }
  606. BOOL
  607. FileVerOs (
  608. IN PDBATTRIB_PARAMS AttribParams,
  609. IN PCTSTR Args
  610. )
  611. {
  612. return pHexMatch (GetFileVerOs (AttribParams->FileParams->NativeObjectName), Args);
  613. }
  614. BOOL
  615. FileVerType (
  616. IN PDBATTRIB_PARAMS AttribParams,
  617. IN PCTSTR Args
  618. )
  619. {
  620. return pHexMatch (GetFileVerType (AttribParams->FileParams->NativeObjectName), Args);
  621. }
  622. BOOL
  623. UpToBinProductVer (
  624. IN PDBATTRIB_PARAMS AttribParams,
  625. IN PCTSTR Args
  626. )
  627. {
  628. VRVALUE_ENUM Version;
  629. ULONGLONG versionStampValue = 0;
  630. ULONGLONG maxValue;
  631. if (VrCreateEnumStruct (&Version, AttribParams->FileParams->NativeObjectName)) {
  632. versionStampValue = VrGetBinaryProductVersion (&Version);
  633. VrDestroyEnumStruct (&Version);
  634. } else {
  635. return FALSE;
  636. }
  637. if (!pConvertDotStringToValue (Args, &maxValue)) {
  638. DEBUGMSG ((DBG_WHOOPS, "Invalid value of %s caused UpToBinProductVer to fail", Args));
  639. return FALSE;
  640. }
  641. return versionStampValue <= maxValue;
  642. }
  643. BOOL
  644. UpToBinFileVer (
  645. IN PDBATTRIB_PARAMS AttribParams,
  646. IN PCTSTR Args
  647. )
  648. {
  649. VRVALUE_ENUM Version;
  650. ULONGLONG versionStampValue = 0;
  651. ULONGLONG maxValue;
  652. if (VrCreateEnumStruct (&Version, AttribParams->FileParams->NativeObjectName)) {
  653. versionStampValue = VrGetBinaryFileVersion (&Version);
  654. VrDestroyEnumStruct (&Version);
  655. } else {
  656. return FALSE;
  657. }
  658. if (!pConvertDotStringToValue (Args, &maxValue)) {
  659. DEBUGMSG ((DBG_WHOOPS, "Invalid value of %s caused UpToBinFileVer to fail", Args));
  660. return FALSE;
  661. }
  662. return versionStampValue <= maxValue;
  663. }