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.

2027 lines
46 KiB

  1. #ifndef __SDBP_H__
  2. #define __SDBP_H__
  3. #ifndef SDB_ANSI_LIB
  4. #define UNICODE
  5. #define _UNICODE
  6. #endif
  7. #include <assert.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <memory.h>
  12. #include <malloc.h>
  13. #include <stddef.h>
  14. #ifndef KERNEL_MODE
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <windows.h>
  19. #else // KERNEL_MODE
  20. #include <ntosp.h>
  21. #include <zwapi.h>
  22. #include <ntimage.h>
  23. #include <windef.h>
  24. #include <winver.h>
  25. #include <winerror.h>
  26. #include <stdarg.h>
  27. #include <ntldr.h>
  28. #define NtCreateFile ZwCreateFile
  29. #define NtClose ZwClose
  30. #define NtReadFile ZwReadFile
  31. #define NtOpenKey ZwOpenKey
  32. #define NtQueryValueKey ZwQueryValueKey
  33. #define NtMapViewOfSection ZwMapViewOfSection
  34. #define NtUnmapViewOfSection ZwUnmapViewOfSection
  35. #define NtOpenFile ZwOpenFile
  36. #define NtQueryInformationFile ZwQueryInformationFile
  37. #ifndef MAKEINTRESOURCE
  38. #define MAKEINTRESOURCEW(i) (LPWSTR)((ULONG_PTR)((WORD)(i)))
  39. #define MAKEINTRESOURCE MAKEINTRESOURCEW
  40. #endif // not defined MAKEINTRESOURCE
  41. #ifndef RT_VERSION
  42. #define RT_VERSION MAKEINTRESOURCE(16)
  43. #endif // not defined RT_VERSION
  44. #ifndef INVALID_HANDLE_VALUE
  45. #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
  46. #endif // not defined INVALID_HANDLE_VALUE
  47. #ifndef SEC_COMMIT
  48. #define SEC_COMMIT 0x8000000
  49. #endif
  50. #endif // KERNEL_MODE
  51. #include <tchar.h>
  52. #include "shimdb.h"
  53. #define MAX_INDEXES 10
  54. #define TABLETPC_KEY_PATH TEXT("System\\WPA\\TabletPC")
  55. #define EHOME_KEY_PATH TEXT("SYSTEM\\WPA\\MediaCenter")
  56. #define IS_OS_INSTALL_VALUE TEXT("Installed")
  57. //
  58. // This is a flag stored for each index.
  59. // Currently it is only used to flag "unique key" types.
  60. //
  61. #define SHIMDB_INDEX_UNIQUE_KEY 0x00000001
  62. // index could be of 2 types:
  63. // containing simply all record and containing only
  64. // "unique" keys with the records linked (the records have to be sorted for this
  65. // type of index to work)
  66. typedef struct _INDEX_INFO {
  67. TAGID tiIndex; // points at the INDEX_BITS tag
  68. TAG tWhich; // what tag is being indexed
  69. TAG tKey; // what subtag is the key?
  70. BOOL bActive; // are we actually indexing now?
  71. BOOL bUniqueKey; // are the keys unique?
  72. ULONGLONG ullLastKey;
  73. DWORD dwIndexEntry; // offset to the next available index entry
  74. DWORD dwIndexEnd; // one byte past the end of the index block
  75. DWORD dwFlags;
  76. } INDEX_INFO, *PINDEX_INFO;
  77. //
  78. // Flags for use in DB structure DB.dwFlags
  79. //
  80. #define DB_IN_MEMORY 0x00000001
  81. #define DB_GUID_VALID 0x00000002
  82. typedef struct _DB {
  83. // used for both read and write
  84. HANDLE hFile;
  85. PVOID pBase; // for both memory-mapping & buffered writes
  86. BOOL bWrite; // was it opened with create?
  87. DWORD dwSize; // the size of the whole db, in bytes
  88. DWORD dwFlags; // flags (such as IN-memory flag)
  89. GUID guidDB; // optional id for the database
  90. DWORD dwIndexes; // the number of indexes
  91. INDEX_INFO aIndexes[MAX_INDEXES]; // data for the indexes
  92. // stuff that's used for read
  93. HANDLE hSection; // for memory-mapping
  94. TAGID tiStringTable; // pointer to the stringtable for string handling
  95. BOOL bIndexesScanned; // have the indexes been looked at?
  96. // stuff that's used for write
  97. struct _DB* pdbStringTable; // stringtable is a subdatabase that's created on the side
  98. PVOID pStringHash; // stringtable hash (same info as in stringtable)
  99. DWORD dwAllocatedSize; // the size allocated for buffered writes
  100. BOOL bWritingIndexes; // are we in the process of allocating index space?
  101. TAGID tiIndexes; // used during index allocation
  102. //
  103. // BUGBUG Hack alert read from unaligned (v1.0) database is enabled here
  104. //
  105. BOOL bUnalignedRead;
  106. #ifdef WIN32A_MODE
  107. PVOID pHashStringBody; // hash of the strings located within the body
  108. PVOID pHashStringTable; // hash for the strings in the stringtable
  109. #endif
  110. #ifndef WIN32A_MODE
  111. UNICODE_STRING ustrTempStringtable; // string table temp filename
  112. #else
  113. LPCTSTR pszTempStringtable;
  114. #endif
  115. } DB, *PDB;
  116. //
  117. // We're using the high 4 bits of the TAGID to
  118. // say what PDB the TAGID is from. Kludge? Perhaps.
  119. //
  120. #define PDB_MAIN 0x00000000
  121. #define PDB_TEST 0x10000000
  122. // all other entries are local (custom) pdbs
  123. #define PDB_LOCAL 0x20000000
  124. #define TAGREF_STRIP_TAGID 0x0FFFFFFF
  125. #define TAGREF_STRIP_PDB 0xF0000000
  126. typedef WCHAR* PWSZ;
  127. ULONG
  128. ShimExceptionHandler(
  129. PEXCEPTION_POINTERS pexi,
  130. char* pszFile,
  131. DWORD dwLine
  132. );
  133. #if DBG
  134. #define SHIM_EXCEPT_HANDLER ShimExceptionHandler(GetExceptionInformation(), __FILE__, __LINE__)
  135. #else
  136. #define SHIM_EXCEPT_HANDLER ShimExceptionHandler(GetExceptionInformation(), "", 0)
  137. #endif
  138. //
  139. // Function prototypes for use in attributes.c (from version.dll)
  140. //
  141. //
  142. typedef DWORD (WINAPI* PFNGetFileVersionInfoSize) (LPTSTR lptstrFilename,
  143. LPDWORD lpdwHandle);
  144. typedef BOOL (WINAPI* PFNGetFileVersionInfo)(LPTSTR lpstrFilename,
  145. DWORD dwHandle,
  146. DWORD dwLen,
  147. LPVOID lpData);
  148. typedef BOOL (WINAPI* PFNVerQueryValue)(const LPVOID pBlock,
  149. LPTSTR lpSubBlock,
  150. LPVOID* lplpBuffer,
  151. PUINT puLen);
  152. #ifdef WIN32A_MODE
  153. #define VERQUERYVALUEAPINAME "VerQueryValueA"
  154. #define GETFILEVERSIONINFOAPINAME "GetFileVersionInfoA"
  155. #define GETFILEVERSIONINFOSIZEAPINAME "GetFileVersionInfoSizeA"
  156. #else
  157. #define VERQUERYVALUEAPINAME "VerQueryValueW"
  158. #define GETFILEVERSIONINFOAPINAME "GetFileVersionInfoW"
  159. #define GETFILEVERSIONINFOSIZEAPINAME "GetFileVersionInfoSizeW"
  160. #endif
  161. //
  162. // custom db cache entry and header
  163. //
  164. typedef struct tagUSERSDBLOOKUPENTRY {
  165. ULARGE_INTEGER liTimeStamp; // we don't need this item, but just for debugging ...
  166. GUID guidDB;
  167. } USERSDBLOOKUPENTRY, *PUSERSDBLOOKUPENTRY;
  168. //
  169. // Lookup vectors
  170. //
  171. //
  172. typedef struct tagUSERSDBLOOKUP {
  173. struct tagUSERSDBLOOKUP* pNext;
  174. struct tagUSERSDBLOOKUP* pPrev;
  175. LPWSTR pwszItemName; // item name
  176. BOOL bLayer; // true if layer
  177. DWORD dwCount; // item count
  178. USERSDBLOOKUPENTRY rgEntries[1]; // actual names
  179. } USERSDBLOOKUP, *PUSERSDBLOOKUP;
  180. //
  181. // HSDB flags
  182. //
  183. #define HSDBF_USE_ATTRIBUTES 0x00000001
  184. #define MAX_SDBS 16
  185. /*++
  186. Flags for use with SdbOpenLocalDatabaseEx
  187. --*/
  188. #define SDBCUSTOM_GUID 0x00000001 // this is a "type" -- when specified, database guid is used to find/open the database
  189. #define SDBCUSTOM_GUID_BINARY 0x00000001 // guid is provided in binary form
  190. #define SDBCUSTOM_GUID_STRING 0x00010001 // guid is provided as a string "{....}"
  191. #define SDBCUSTOM_PATH 0x00000002 // when specified, database path is used to find/open the database
  192. #define SDBCUSTOM_PATH_DOS 0x00000002 // path is provided in dos form
  193. #define SDBCUSTOM_PATH_NT 0x00010002 // path is provided in nt form
  194. #define SDBCUSTOM_USE_INDEX 0x10000000 // when specified, an index is provided to use a particular entry within the sdb table
  195. #define SDBCUSTOM_FLAGS(dwFlags) ((dwFlags) & 0xFFFF0000)
  196. #define SDBCUSTOM_TYPE(dwFlags) ((dwFlags) & 0x0FFFF)
  197. #define SDBCUSTOM_SET_MASK(hSDB, dwIndex) \
  198. (((PSDBCONTEXT)hSDB)->dwDatabaseMask |= (1 << (dwIndex)))
  199. #define SDBCUSTOM_CLEAR_MASK(hSDB, dwIndex) \
  200. (((PSDBCONTEXT)hSDB)->dwDatabaseMask &= ~(1 << (dwIndex)))
  201. #define SDBCUSTOM_CHECK_INDEX(hSDB, dwIndex) \
  202. (((PSDBCONTEXT)hSDB)->dwDatabaseMask & (1 << (dwIndex)))
  203. #define SDB_CUSTOM_MASK 0x0FFF8 // except 0, 1 and 2 -- bits for main, test and local
  204. /*++
  205. These macros convert from the mask form (as found in TAGREF's high 4 bits) to
  206. index form and back
  207. --*/
  208. #define SDB_MASK_TO_INDEX(dwMask) ((((DWORD)(dwMask)) >> 28) & 0x0F)
  209. #define SDB_INDEX_TO_MASK(dwIndex) (((DWORD)(dwIndex)) << 28)
  210. typedef struct tagSDBENTRY {
  211. GUID guidDB; // guid of a custom db
  212. PDB pdb; // pdb for the db
  213. DWORD dwFlags; // see SDBENTRY_ flags
  214. } SDBENTRY, *PSDBENTRY;
  215. /*++
  216. Given a context and index (or mask) for an sdb - retrieve a pointer to
  217. the appropriate entry (PSDBENTRY)
  218. --*/
  219. #define SDBGETENTRY(hSDB, dwIndex) \
  220. (&((PSDBCONTEXT)hSDB)->rgSDB[dwIndex])
  221. #define SDBGETENTRYBYMASK(hSDB, dwMask) \
  222. SDBGETENTRY(hSDB, SDB_MASK_TO_INDEX(dwMask))
  223. /*++
  224. Retrieve main, test and temporary entries respectively
  225. --*/
  226. #define SDBGETMAINENTRY(hSDB) SDBGETENTRY(hSDB, SDB_MASK_TO_INDEX(PDB_MAIN))
  227. #define SDBGETTESTENTRY(hSDB) SDBGETENTRY(hSDB, SDB_MASK_TO_INDEX(PDB_TEST))
  228. #define SDBGETLOCALENTRY(hSDB) SDBGETENTRY(hSDB, SDB_MASK_TO_INDEX(PDB_LOCAL))
  229. #define SDB_LOCALDB_INDEX SDB_MASK_TO_INDEX(PDB_LOCAL)
  230. #define SDB_FIRST_ENTRY_INDEX 3 // since 0 is main, 1 is test and 2 is local
  231. /*++
  232. Flags that are valid in SDBENTRY.dwFlags
  233. --*/
  234. #define SDBENTRY_VALID_GUID 0x00000001 // indicated that an entry has valid guid for lookup
  235. #define SDBENTRY_VALID_ENTRY 0x00000002 // indicates whether an entry is free
  236. #define SDBENTRY_INVALID_INDEX ((DWORD)-1)
  237. /*++
  238. Macros that allow us access to some of the members of hSDB w/o derefencing the type
  239. Makes it a bit easier of the typecasts in code
  240. --*/
  241. #ifdef WIN32A_MODE
  242. #define SDBCONTEXT_IS_INSTRUMENTED(hSDB) FALSE
  243. #define SDBCONTEXT_GET_PIPE(hSDB) INVALID_HANDLE_VALUE
  244. #else
  245. #define SDBCONTEXT_GET_PIPE(hSDB) \
  246. (((PSDBCONTEXT)(hSDB))->hPipe)
  247. #define SDBCONTEXT_IS_INSTRUMENTED(hSDB) \
  248. (((PSDBCONTEXT)(hSDB))->hPipe != INVALID_HANDLE_VALUE)
  249. #endif
  250. typedef struct tagSDBCONTEXT {
  251. DWORD dwFlags;
  252. //
  253. // Database handles
  254. //
  255. PDB pdbMain; // main database (sysmain)
  256. PDB pdbTest; // test database (systest)
  257. PDB pdbLocal; // local database
  258. //
  259. // database table
  260. //
  261. DWORD dwDatabaseCount; // number of entries in the table below
  262. DWORD dwDatabaseMask; // bit-field mask for databases
  263. SDBENTRY rgSDB[MAX_SDBS];
  264. //
  265. // Pointer to the file attribute cache (see attributes.c for details)
  266. //
  267. PVOID pFileAttributeCache;
  268. //
  269. // function pointers for use with version.dll
  270. // (see attributes.c)
  271. //
  272. PFNVerQueryValue pfnVerQueryValue;
  273. PFNGetFileVersionInfo pfnGetFileVersionInfo;
  274. PFNGetFileVersionInfoSize pfnGetFileVersionInfoSize;
  275. //
  276. // processor architecture, cached to perform checks of RUNTIME_PLATFORM
  277. //
  278. DWORD dwRuntimePlatform;
  279. //
  280. // OS SKU
  281. //
  282. DWORD dwOSSKU;
  283. //
  284. // OS SP mask
  285. //
  286. DWORD dwSPMask;
  287. //
  288. // User SDB cache
  289. //
  290. PUSERSDBLOOKUP pLookupHead;
  291. #ifndef WIN32A_MODE
  292. //
  293. // debug pipe
  294. //
  295. HANDLE hPipe;
  296. #endif // WIN32A_MODE
  297. } SDBCONTEXT, *PSDBCONTEXT;
  298. //
  299. // These flags are used to direct
  300. // SearchDB routine not to use process_history or
  301. // to prepare for lookup in local DB
  302. //
  303. #define SEARCHDBF_INITIALIZED 0x00000001
  304. #define SEARCHDBF_NO_PROCESS_HISTORY 0x00000002
  305. //
  306. // note the gap here -- there was a flag related to local dbs - it's
  307. // defunct and has been removed
  308. //
  309. #define SEARCHDBF_NO_ATTRIBUTE_CACHE 0x00000008
  310. #define SEARCHDBF_NO_LFN 0x00000010
  311. typedef struct tagSEARCHPATHPART {
  312. LPCTSTR pszPart;
  313. ULONG PartLength;
  314. } SEARCHPATHPART, *PSEARCHPATHPART;
  315. typedef struct tagSEARCHPATH {
  316. ULONG PartCount; // count parts
  317. SEARCHPATHPART Parts[];
  318. } SEARCHPATHPARTS, *PSEARCHPATHPARTS;
  319. typedef struct tagSEARCHDBCONTEXT {
  320. DWORD dwFlags; // flags directing how the context is used
  321. // we may, for instance, not want to use ProcessHistory
  322. // at all SEARCHDBF* flags apply
  323. HANDLE hMainFile; // handle of the main file we are checking
  324. LPVOID pImageBase; // pointer to image base for the main file. We will use the image pointer
  325. DWORD dwImageSize; // image size as provided by k-mode code
  326. LPTSTR szDir; // directory, we allocate it, we free it
  327. LPTSTR szName; // filename for the file we're looking up, we allocate and free it
  328. LPTSTR szModuleName; // for 16-bit apps only; we allocate and free
  329. LPCTSTR pEnvironment; // we DON'T touch this at all
  330. LPTSTR szProcessHistory; // buffer for the search path string (unparsed), allocated by us, we free it
  331. PSEARCHPATHPARTS pSearchParts; // search path undone, we allocate and free it
  332. } SEARCHDBCONTEXT, *PSEARCHDBCONTEXT;
  333. // HASH structures
  334. typedef struct tagStringHashElement {
  335. TCHAR* szStr; // the string itself (points past buffer)
  336. STRINGREF srStr; // stringref (where the string is)
  337. struct tagStringHashElement* pNext;
  338. } STRHASHELEMENT, *PSTRHASHELEMENT;
  339. typedef struct tagStringHash {
  340. DWORD dwHashSize; // hash size
  341. PSTRHASHELEMENT* pTable;
  342. } STRHASH, *PSTRHASH;
  343. #ifndef WIN32A_MODE
  344. //
  345. // apphelp info stuff (see apphelp.c)
  346. //
  347. //
  348. // dwContextFlags can have these values:
  349. //
  350. #define AHC_DBDETAILS_NOCLOSE 0x00000001
  351. #define AHC_HSDB_NOCLOSE 0x00000002
  352. typedef struct tagAPPHELPINFOCONTEXT {
  353. HSDB hSDB; // handle to the database
  354. PDB pdb; // pdb where we have exe or null (we work through hsdb then
  355. PDB pdbDetails; // pdb where we have details
  356. DWORD dwDatabaseType; // this is the database type (of the db that contains the match)
  357. DWORD dwContextFlags; // flags specific to the context
  358. GUID guidDB; // database guid
  359. GUID guidID; // guid of the matching entry
  360. DWORD dwMask; // mask which tells us whether members are valid
  361. TAGID tiExe; // tagid of an exe entry
  362. TAGID tiApphelpExe; // apphelp in the main db
  363. DWORD dwHtmlHelpID; // html help id
  364. DWORD dwSeverity;
  365. DWORD dwFlags;
  366. TAGID tiApphelpDetails; // apphelp stuff in the details db
  367. TAGID tiLink;
  368. LPCWSTR pwszAppName;
  369. LPCWSTR pwszApphelpURL;
  370. LPCWSTR pwszVendorName;
  371. LPCWSTR pwszExeName;
  372. LPCWSTR pwszLinkURL;
  373. LPCWSTR pwszLinkText;
  374. LPCWSTR pwszTitle;
  375. LPCWSTR pwszDetails;
  376. LPCWSTR pwszContact;
  377. LPWSTR pwszHelpCtrURL; // help center URL
  378. BOOL bOfflineContent; // pass FALSE
  379. BOOL bUseHtmlHelp; // pass FALSE
  380. UNICODE_STRING ustrChmFile;
  381. UNICODE_STRING ustrDetailsDatabase;
  382. } APPHELPINFOCONTEXT, *PAPPHELPINFOCONTEXT;
  383. #endif // WIN32A_MODE
  384. void* SdbAlloc(size_t size);
  385. void SdbFree(void* pWhat);
  386. // Base primitives.
  387. HANDLE
  388. SdbpOpenFile(
  389. LPCTSTR szPath,
  390. PATH_TYPE eType
  391. );
  392. #if defined(WIN32A_MODE) || defined(WIN32U_MODE)
  393. #define SdbpCloseFile(hFile) CloseHandle(hFile)
  394. #else
  395. #define SdbpCloseFile(hFile) NtClose(hFile)
  396. #endif
  397. BOOL
  398. SdbpCreateSearchPathPartsFromPath(
  399. IN LPCTSTR pszPath,
  400. OUT PSEARCHPATHPARTS* ppSearchPathParts
  401. );
  402. BOOL
  403. SdbpGetLongFileName(
  404. IN LPCTSTR szFullPath,
  405. OUT LPTSTR szLongFileName
  406. );
  407. void
  408. SdbpGetWinDir(
  409. LPTSTR pwszDir
  410. );
  411. void
  412. SdbpGetAppPatchDir(
  413. LPTSTR szAppPatchPath
  414. );
  415. DWORD
  416. SdbExpandEnvironmentStrings(
  417. IN LPCTSTR lpSrc,
  418. OUT LPTSTR lpDst,
  419. IN DWORD nSize);
  420. BOOL
  421. SdbpGUIDFromString(
  422. LPCTSTR lpszGuid,
  423. GUID* pGuid
  424. );
  425. DWORD
  426. SdbpGetStringRefLength(
  427. HSDB hSDB,
  428. TAGREF trString
  429. );
  430. LPCTSTR
  431. SdbpGetStringRefPtr(
  432. IN HSDB hSDB,
  433. IN TAGREF trString
  434. );
  435. BOOL
  436. SdbpWriteBitsToFile(
  437. LPCTSTR szFile,
  438. PBYTE pBuffer,
  439. DWORD dwSize
  440. );
  441. // DB access primitives
  442. void
  443. SdbCloseDatabaseRead(
  444. PDB pdb
  445. );
  446. BOOL
  447. SdbpOpenAndMapDB(
  448. PDB pdb,
  449. LPCTSTR pszPath,
  450. PATH_TYPE eType
  451. );
  452. PDB
  453. SdbpOpenDatabaseInMemory(
  454. LPVOID pImageDatabase,
  455. DWORD dwSize
  456. );
  457. BOOL
  458. SdbpUnmapAndCloseDB(
  459. PDB pdb
  460. );
  461. DWORD
  462. SdbpGetFileSize(
  463. HANDLE hFile
  464. );
  465. BOOL
  466. SdbpReadMappedData(
  467. PDB pdb,
  468. DWORD dwOffset,
  469. PVOID pBuffer,
  470. DWORD dwSize
  471. );
  472. PVOID
  473. SdbpGetMappedData(
  474. PDB pdb,
  475. DWORD dwOffset
  476. );
  477. TAGID
  478. SdbpGetNextTagId(
  479. PDB pdb,
  480. TAGID tiWhich
  481. );
  482. DWORD
  483. SdbpGetStandardDatabasePath(
  484. IN DWORD dwDatabaseType,
  485. IN DWORD dwFlags, // specify HID_DOS_PATHS for dos paths
  486. OUT LPTSTR pszDatabasePath,
  487. IN DWORD dwBufferSize // in tchars
  488. );
  489. LPTSTR
  490. GetProcessHistory(
  491. IN LPCTSTR pEnvironment,
  492. IN LPTSTR szDir,
  493. IN LPTSTR szName
  494. );
  495. void
  496. PrepareFormatForUnicode(
  497. PCH fmtUnicode,
  498. PCH format
  499. );
  500. #ifndef WIN32A_MODE
  501. #define PREPARE_FORMAT(pszFormat, Format) \
  502. { \
  503. STACK_ALLOC(pszFormat, (strlen(Format) + 1) * sizeof(*Format)); \
  504. if (pszFormat != NULL) { \
  505. PrepareFormatForUnicode(pszFormat, Format); \
  506. } \
  507. }
  508. #define CONVERT_FORMAT(pwsz, psz) \
  509. { \
  510. ANSI_STRING str; \
  511. UNICODE_STRING ustr; \
  512. ULONG Length; \
  513. NTSTATUS Status; \
  514. \
  515. RtlInitAnsiString(&str, (psz)); \
  516. Length = RtlAnsiStringToUnicodeSize(&str); \
  517. pwsz = (LPWSTR)_alloca(Length); \
  518. \
  519. if (pwsz != NULL) { \
  520. ustr.MaximumLength = (USHORT)Length; \
  521. ustr.Buffer = pwsz; \
  522. Status = RtlAnsiStringToUnicodeString(&ustr, &str, FALSE); \
  523. if (!NT_SUCCESS(Status)) { \
  524. pwsz = NULL; \
  525. } \
  526. } \
  527. }
  528. #else // WIN32A_MODE
  529. #define PREPARE_FORMAT(pszFormat, Format) (pszFormat = (Format))
  530. #define CONVERT_FORMAT(pwsz, psz) (pwsz = (psz))
  531. #endif // WIN32A_MODE
  532. #ifdef KERNEL_MODE
  533. #define SdbpGetWow64Flag() KEY_WOW64_64KEY
  534. #else // !KERNEL_MODE
  535. DWORD SdbpGetWow64Flag(VOID);
  536. #endif // KERNEL_MODE
  537. // READ
  538. DWORD
  539. SdbpGetTagHeadSize(
  540. PDB pdb,
  541. TAGID tiWhich
  542. );
  543. TAGID
  544. SdbpGetLibraryFile(
  545. IN PDB pdb, // handle to the database channel
  546. IN LPCTSTR szDllName // the name of the FILE to find in LIBRARY (main db only)
  547. );
  548. #define SdbpGetMainLibraryFile(hSDB, szFileName) \
  549. SdbpGetLibraryFile(((PSDBCONTEXT)(hSDB))->pdbMain, (szFileName))
  550. STRINGREF SdbpReadStringRef(PDB pdb, TAGID tiWhich);
  551. BOOL SdbpReadStringFromTable(PDB pdb, STRINGREF srData, LPTSTR szBuffer, DWORD dwBufferSize);
  552. //
  553. // Custom db stuff
  554. //
  555. VOID
  556. SdbpCleanupUserSDBCache(
  557. IN PSDBCONTEXT pSdbContext
  558. );
  559. HANDLE
  560. SdbpCreateKeyPath(
  561. LPCWSTR pwszPath,
  562. BOOL bMachine
  563. );
  564. BOOL
  565. SdbOpenNthLocalDatabase(
  566. IN HSDB hSDB, // handle to the database channel
  567. IN LPCTSTR pszItemName, // the name of the exectutable, without the path or the layer name
  568. IN LPDWORD pdwIndex, // zero based index of the local DB to open
  569. IN BOOL bLayer
  570. );
  571. BOOL
  572. SdbpAddMatch( // internal function see sdbapi for more info
  573. IN OUT PSDBQUERYRESULT pQueryResult,
  574. IN PSDBCONTEXT pSdbContext,
  575. IN PDB pdb,
  576. IN TAGID* ptiExes,
  577. IN DWORD dwNumExes,
  578. IN TAGID* ptiLayers,
  579. IN DWORD dwNumLayers,
  580. IN GUID* pguidExeID,
  581. IN DWORD dwExeFlags,
  582. IN OUT PMATCHMODE pMode
  583. );
  584. BOOL
  585. SdbOpenLocalDatabaseEx(
  586. IN HSDB hSDB,
  587. IN LPCVOID pDatabaseID,
  588. IN DWORD dwFLags,
  589. OUT PDB* pPDB OPTIONAL,
  590. IN OUT LPDWORD pdwLocalDBMask OPTIONAL // local db mask for tagref
  591. );
  592. BOOL
  593. SdbCloseLocalDatabaseEx(
  594. IN HSDB hSDB,
  595. IN PDB pdb,
  596. IN DWORD dwIndex
  597. );
  598. BOOL
  599. SdbpIsMainPDB(
  600. IN HSDB hSDB,
  601. IN PDB pdb
  602. );
  603. BOOL
  604. SdbpIsLocalTempPDB(
  605. IN HSDB hSDB,
  606. IN PDB pdb
  607. );
  608. DWORD
  609. SdbpRetainLocalDBEntry(
  610. IN HSDB hSDB,
  611. OUT PDB* ppPDB OPTIONAL // optional pointer to the pdb
  612. );
  613. BOOL
  614. SdbpCleanupLocalDatabaseSupport(
  615. IN HSDB hSDB
  616. );
  617. BOOL
  618. SdbpFindLocalDatabaseByGUID(
  619. IN HSDB hSDB,
  620. IN GUID* pGuidDB,
  621. IN BOOL bExcludeLocalDB,
  622. OUT LPDWORD pdwIndex
  623. );
  624. BOOL
  625. SdbpFindLocalDatabaseByPDB(
  626. IN HSDB hSDB,
  627. IN PDB pdb,
  628. IN BOOL bExcludeLocalDB, // exclude local temp db entry?
  629. OUT LPDWORD pdwIndex
  630. );
  631. LPCTSTR
  632. SdbpGetDatabaseDescriptionPtr(
  633. IN PDB pdb
  634. );
  635. // HASH
  636. PVOID
  637. HashCreate(
  638. void
  639. );
  640. void
  641. HashFree(
  642. PVOID pStringHash
  643. );
  644. DWORD
  645. HashString(
  646. PSTRHASH pHash,
  647. LPCTSTR szString
  648. );
  649. DWORD
  650. HashStringRef(
  651. PSTRHASH pHash,
  652. STRINGREF srString);
  653. // BULK
  654. BOOL
  655. SdbpReadMappedData(
  656. PDB pdb,
  657. DWORD dwOffset,
  658. PVOID pBuffer,
  659. DWORD dwSize
  660. );
  661. BOOL
  662. SdbpCheckForMatch(
  663. HSDB pDBContext,
  664. PDB pdb,
  665. TAGID tiExe,
  666. PSEARCHDBCONTEXT pContext,
  667. PMATCHMODE pMMode,
  668. GUID* pGUID,
  669. DWORD* pdwFlags
  670. );
  671. BOOL
  672. bGetExeID(
  673. PDB pdb,
  674. TAGID tiExe,
  675. GUID* pGuid
  676. );
  677. BOOL
  678. SdbpBinarySearchUnique(
  679. PINDEX_RECORD pRecords,
  680. DWORD nRecords,
  681. ULONGLONG ullKey,
  682. DWORD* pdwIndex
  683. );
  684. BOOL
  685. SdbpBinarySearchFirst(
  686. PINDEX_RECORD pRecords,
  687. DWORD nRecords,
  688. ULONGLONG ullKey,
  689. DWORD* pdwIndex
  690. );
  691. char*
  692. SdbpKeyToAnsiString(
  693. ULONGLONG ullKey,
  694. char* szString
  695. );
  696. // ATTRIBUTES
  697. BOOL
  698. SafeNCat(
  699. LPTSTR lpszDest,
  700. int nSize,
  701. LPCTSTR lpszSrc,
  702. int nSizeAppend
  703. );
  704. BOOL
  705. SdbpSanitizeXML(
  706. LPTSTR pchOut,
  707. int nSize,
  708. LPCTSTR lpszXML
  709. );
  710. ////////////////////////////////////////////////////////////////////////////
  711. //
  712. // Image File Data
  713. // Helpful structure that is used in functions dealing with
  714. // image properties retrieval
  715. //
  716. typedef struct tagIMAGEFILEDATA {
  717. HANDLE hFile; // we do not manage this
  718. DWORD dwFlags; // flags that tell us not to mess with the file's handle
  719. HANDLE hSection; // section of the fileview
  720. PVOID pBase; // base ptr
  721. SIZE_T ViewSize; // size of the view
  722. ULONGLONG FileSize; // size of the file
  723. } IMAGEFILEDATA, *PIMAGEFILEDATA;
  724. #define IMAGEFILEDATA_HANDLEVALID 0x00000001
  725. #define IMAGEFILEDATA_NOFILECLOSE 0x00000002
  726. #define IMAGEFILEDATA_PBASEVALID 0x00000004
  727. #define IMAGEFILEDATA_NOFILEMAP 0x00000008
  728. //
  729. // FILEINFORMATION structure used in file attribute cache, see attributes.c
  730. //
  731. //
  732. typedef struct tagFILEINFORMATION {
  733. //
  734. // "Signature" to insure that it's legitimate memory when
  735. // operating of file attributes
  736. //
  737. DWORD dwMagic;
  738. HANDLE hFile; // we store this handle
  739. LPVOID pImageBase;
  740. DWORD dwImageSize;
  741. //
  742. // pointer to the next item in cache
  743. //
  744. struct tagFILEINFORMATION* pNext; // pointer to the next item in cache
  745. LPTSTR FilePath; // file name with path (allocated by us with this struct)
  746. DWORD dwFlags; // flags
  747. PVOID pVersionInfo; // version info ptr, retained (allocated by us)
  748. LPTSTR pDescription16; // string, points to the buffer for 16-bit description
  749. LPTSTR pModuleName16; // string, points to the buffer for 16-bit module name
  750. ATTRINFO Attributes[];
  751. } FILEINFO, *PFILEINFO;
  752. //
  753. // This structure is used to recover directory-related attributes of a file
  754. // we used to have time here as well... but not anymore
  755. // only low part of the file size is of any significance
  756. //
  757. typedef struct tagFILEDIRECTORYATTRIBUTES {
  758. DWORD dwFlags; // flags that show which attributes are valid
  759. DWORD dwFileSizeHigh;
  760. DWORD dwFileSizeLow;
  761. } FILEDIRECTORYATTRIBUTES, *PFILEDIRECTORYATTRIBUTES;
  762. //
  763. // Attribute names. Use SdbTagToString if you want to get the name of
  764. // a tag ID.
  765. //
  766. typedef struct _TAG_INFO {
  767. TAG tWhich;
  768. TCHAR* szName;
  769. } TAG_INFO, *PTAG_INFO;
  770. typedef struct _MOD_TYPE_STRINGS {
  771. DWORD dwModuleType;
  772. LPTSTR szModuleType;
  773. } MOD_TYPE_STRINGS;
  774. typedef struct tagLANGANDCODEPAGE {
  775. WORD wLanguage;
  776. WORD wCodePage;
  777. } LANGANDCODEPAGE, *PLANGANDCODEPAGE;
  778. BOOL
  779. SdbpGetHeaderAttributes(
  780. IN PSDBCONTEXT pContext,
  781. OUT PFILEINFO pFileInfo
  782. );
  783. LPTSTR
  784. SdbpQueryVersionString(
  785. HSDB hSDB,
  786. PVOID pVersionData,
  787. PLANGANDCODEPAGE pTranslations,
  788. DWORD dwCount,
  789. LPCTSTR szString
  790. );
  791. BOOL
  792. SdbpGetFileChecksum(
  793. PULONG pChecksum,
  794. PIMAGEFILEDATA pImageData
  795. );
  796. BOOL
  797. SdbpGetModulePECheckSum(
  798. PULONG pChecksum,
  799. LPDWORD pdwLinkerVersion,
  800. LPDWORD pdwLinkDate,
  801. PIMAGEFILEDATA pImageData
  802. );
  803. BOOL
  804. SdbpCheckVersion(
  805. ULONGLONG qwDBFileVer,
  806. ULONGLONG qwBinFileVer
  807. );
  808. BOOL
  809. SdbpCheckUptoVersion(
  810. ULONGLONG qwDBFileVer,
  811. ULONGLONG qwBinFileVer
  812. );
  813. #ifdef KERNEL_MODE
  814. //
  815. // Special versions of functions for kernel-mode implementation (in ntkmode.c).
  816. //
  817. BOOL
  818. SdbpGetFileDirectoryAttributesNT(
  819. PFILEINFO pFileInfo,
  820. PIMAGEFILEDATA pImageData
  821. );
  822. BOOL
  823. SdbpQueryFileDirectoryAttributesNT(
  824. PIMAGEFILEDATA pImageData,
  825. PFILEDIRECTORYATTRIBUTES pFileDirectoryAttributes
  826. );
  827. #else
  828. BOOL
  829. SdbpGetFileDirectoryAttributes(
  830. OUT PFILEINFO pFileInfo
  831. );
  832. BOOL
  833. SdbpGetVersionAttributes(
  834. IN PSDBCONTEXT pContext,
  835. OUT PFILEINFO pFileInfo
  836. );
  837. #endif // KERNEL_MODE
  838. int
  839. TagToIndex(
  840. IN TAG tag // the tag
  841. );
  842. BOOL
  843. SdbpSetAttribute(
  844. OUT PFILEINFO pFileInfo, // pointer to the FILEINFO structure.
  845. IN TAG AttrID, // Attribute ID (tag, as in TAG_SIZE
  846. IN PVOID pValue // value
  847. );
  848. void
  849. SdbpQueryStringVersionInformation(
  850. IN PSDBCONTEXT pContext,
  851. IN PFILEINFO pFileInfo,
  852. OUT LPVOID pVersionInfo
  853. );
  854. VOID
  855. SdbpQueryBinVersionInformation(
  856. IN PSDBCONTEXT pContext,
  857. IN PFILEINFO pFileInfo,
  858. OUT VS_FIXEDFILEINFO* pFixedInfo
  859. );
  860. BOOL
  861. SdbpGetAttribute(
  862. IN PSDBCONTEXT pContext,
  863. OUT PFILEINFO pFileInfo,
  864. IN TAG AttrID
  865. );
  866. BOOL
  867. SdbpGetImageNTHeader(
  868. OUT PIMAGE_NT_HEADERS* ppHeader,
  869. IN PIMAGEFILEDATA pImageData
  870. );
  871. BOOL
  872. SdbpGetVersionAttributesNT(
  873. PSDBCONTEXT pContext,
  874. PFILEINFO pFileInfo,
  875. PIMAGEFILEDATA pImageData
  876. );
  877. VOID
  878. SdbpCleanupAttributeMgr(
  879. PSDBCONTEXT pContext
  880. );
  881. BOOL
  882. SdbpCheckAttribute(
  883. HSDB hSDB,
  884. PVOID pFileData,
  885. TAG tAttrID,
  886. PVOID pAttribute
  887. );
  888. BOOL
  889. SdbpCheckAllAttributes(
  890. HSDB hSDB,
  891. PDB pdb,
  892. TAGID tiMatch,
  893. PVOID pFileData);
  894. // READ FUNCTIONS
  895. BOOL SdbpReadTagData(PDB pdb, TAGID tiWhich, PVOID pBuffer, DWORD dwBufferSize);
  896. // WRITE
  897. BOOL
  898. SdbpWriteTagData(
  899. PDB pdb,
  900. TAG tTag,
  901. const PVOID pBuffer,
  902. DWORD dwSize
  903. );
  904. // STRING FUNCTIONS
  905. WCHAR* SdbpGetMappedStringFromTable(PDB pdb, STRINGREF srData);
  906. STRINGREF SdbpAddStringToTable(PDB pdb, LPCTSTR szData);
  907. // INDEX FUNCTIONS
  908. PINDEX_RECORD
  909. SdbpGetIndex(
  910. PDB pdb,
  911. TAGID tiIndex,
  912. DWORD* pdwNumRecs
  913. );
  914. void
  915. SdbpScanIndexes(
  916. PDB pdb
  917. );
  918. TAGID
  919. SdbpGetFirstIndexedRecord(
  920. PDB pdb,
  921. TAGID tiIndex,
  922. ULONGLONG ullKey,
  923. FIND_INFO* pFindInfo
  924. );
  925. TAGID
  926. SdbpGetNextIndexedRecord(
  927. PDB pdb,
  928. TAGID tiIndex,
  929. FIND_INFO* pFindInfo
  930. );
  931. TAGID
  932. SdbpFindFirstIndexedWildCardTag(
  933. PDB pdb,
  934. TAG tWhich,
  935. TAG tKey,
  936. LPCTSTR szName,
  937. FIND_INFO* pFindInfo
  938. );
  939. TAGID
  940. SdbpFindNextIndexedWildCardTag(
  941. PDB pdb,
  942. FIND_INFO* pFindInfo
  943. );
  944. BOOL
  945. SdbpSortIndex(
  946. PDB pdb,
  947. TAGID tiIndexBits
  948. );
  949. ULONGLONG
  950. SdbpTagToKey(
  951. PDB pdb,
  952. TAGID tiTag
  953. );
  954. // FINDTAG
  955. TAGID
  956. tiFindFirstNamedTag(
  957. PDB pdb,
  958. TAGID tiParent,
  959. TAG tToFind,
  960. TAG tName,
  961. LPCTSTR pszName
  962. );
  963. TAGID
  964. SdbpFindNextNamedTag(
  965. PDB pdb,
  966. TAGID tiParent,
  967. TAGID tiPrev,
  968. TAG tName,
  969. LPCTSTR pszName
  970. );
  971. TAGID
  972. SdbpFindMatchingName(
  973. PDB pdb,
  974. TAGID tiStart,
  975. FIND_INFO* pFindInfo
  976. );
  977. TAGID
  978. SdbpFindMatchingDWORD(
  979. PDB pdb,
  980. TAGID tiStart,
  981. FIND_INFO* pFindInfo
  982. );
  983. TAGID
  984. SdbpFindMatchingGUID(
  985. IN PDB pdb, // DB to use
  986. IN TAGID tiStart, // the tag where to start from
  987. IN FIND_INFO* pFindInfo // pointer to the search context structure
  988. );
  989. BOOL bTagRefToTagID(HSDB, TAGREF trWhich, PDB* ppdb, TAGID* ptiWhich);
  990. DWORD SdbpGetTagRefDataSize(HSDB, TAGREF trWhich);
  991. BOOL SdbpReadBinaryTagRef(HSDB, TAGREF trWhich, PBYTE pBuffer, DWORD dwBufferSize);
  992. //
  993. // Debug functions (pipe-related)
  994. //
  995. HANDLE
  996. SdbpOpenDebugPipe(
  997. VOID
  998. );
  999. BOOL
  1000. SdbpCloseDebugPipe(
  1001. IN HANDLE hPipe
  1002. );
  1003. BOOL
  1004. SdbpWriteDebugPipe(
  1005. HSDB hSDB,
  1006. LPCSTR pszBuffer
  1007. );
  1008. //
  1009. // APPCOMPAT_EXE_DATA
  1010. //
  1011. //
  1012. #define MAX_SHIM_ENGINE_NAME 32
  1013. typedef struct tagAPPCOMPAT_EXE_DATA {
  1014. //
  1015. // WARNING: never ever change the position of 'szShimEngine'.
  1016. //
  1017. // It MUST be the first element of this structure
  1018. //
  1019. // this structure is referenced during installation of
  1020. // an appcompat backend (base\ntdll)
  1021. WCHAR szShimEngine[MAX_SHIM_ENGINE_NAME];
  1022. DWORD dwFlags; // flags (if any)
  1023. DWORD cbSize; // struct size(allocation size)
  1024. DWORD dwMagic; // magic (signature)
  1025. TAGREF atrExes[SDB_MAX_EXES];
  1026. TAGREF atrLayers[SDB_MAX_LAYERS];
  1027. TAGREF trAppHelp; // if there's an apphelp to display
  1028. DWORD dwDatabaseMap; // count local dbs
  1029. GUID rgGuidDB[MAX_SDBS]; // local dbs
  1030. } APPCOMPAT_EXE_DATA, *PAPPCOMPAT_EXE_DATA;
  1031. PVOID SdbpGetMappedTagData(PDB pdb, TAGID tiWhich);
  1032. BOOL bWStrEqual(const WCHAR* szOne, const WCHAR* szTwo);
  1033. BOOL bFlushBufferedData(PDB pdb);
  1034. void vReleaseBufferedData(PDB pdb);
  1035. BOOL SdbpPatternMatchAnsi(LPCSTR pszPattern, LPCSTR pszTestString);
  1036. BOOL SdbpPatternMatch(LPCTSTR pszPattern, LPCTSTR pszTestString);
  1037. //
  1038. // Registry access functions
  1039. //
  1040. //
  1041. typedef WCHAR* PWSZ;
  1042. void
  1043. SdbpQueryAppCompatFlagsByExeID(
  1044. LPCWSTR pwszKeyPath,
  1045. PUNICODE_STRING pustrExeID,
  1046. LPDWORD lpdwFlags
  1047. );
  1048. #ifdef _DEBUG_SPEW
  1049. typedef struct tagDBGLEVELINFO {
  1050. LPCSTR szStrTag;
  1051. INT iLevel;
  1052. } DBGLEVELINFO;
  1053. #define DEBUG_LEVELS 4
  1054. //
  1055. // Shim Debug Level variable
  1056. // In it's initial state -- we have -1 here,
  1057. // further, upon the very first call to ShimDbgPrint, we examine the
  1058. // environment variable -- and then we set it up appropriately
  1059. //
  1060. #define SHIM_DEBUG_UNINITIALIZED 0x0C0FFEE
  1061. #endif // _DEBUG_SPEW
  1062. /*++
  1063. bWStrEqual
  1064. Currently a wrapper for _wcsicmp. Potentially will use a faster
  1065. routine that just checks equality, rather than also trying to get
  1066. less than/greater than.
  1067. --*/
  1068. #define bWStrEqual(s1, s2) (0 == _wcsicmp((s1), (s2)))
  1069. #define ISEQUALSTRING(s1, s2) (0 == _tcsicmp((s1), (s2)))
  1070. /*++
  1071. dwGetTagDataOffset
  1072. Returns the total size of the tag: the tag header plus the tag data.
  1073. Used for skipping past a tag and going to the next tag in the file.
  1074. --*/
  1075. //
  1076. // HACK ALERT BUGBUG
  1077. // remove this when the code to write aligned db has propagated
  1078. // throught
  1079. //
  1080. #define GETTAGDATASIZEALIGNED(pdb, tiWhich) \
  1081. ((pdb)->bUnalignedRead ? (SdbGetTagDataSize(pdb, tiWhich)) : \
  1082. ((SdbGetTagDataSize(pdb, tiWhich) + 1) & (~1)))
  1083. #if 0 // this is good code that we should but back at some point
  1084. #define GETTAGDATASIZEALIGNED(pdb, tiWhich) \
  1085. ((SdbGetTagDataSize(pdb, tiWhich) + 1) & (~1))
  1086. #endif // End good code
  1087. #define GETTAGDATAOFFSET(pdb, tiWhich) \
  1088. (GETTAGDATASIZEALIGNED(pdb, tiWhich) + SdbpGetTagHeadSize(pdb, tiWhich))
  1089. #ifndef WIN32A_MODE
  1090. ///////////////////////////////////////////////////////////////////////////////////
  1091. //
  1092. // UNICODE - specific macros and definitions
  1093. //
  1094. #define IS_MEMORY_EQUAL(p1, p2, Size) RtlEqualMemory(p1, p2, Size)
  1095. #define CONVERT_STRINGPTR(pdb, pwszSrc, tagType, srWhich) ((WCHAR*)pwszSrc)
  1096. #define READ_STRING(pdb, tiWhich, pwszBuffer, dwBufferSize) \
  1097. (SdbpReadTagData((pdb), (tiWhich), (pwszBuffer), (dwBufferSize) * sizeof(WCHAR)))
  1098. //
  1099. // The macro below is a substitution for a function that exists in non-unicode code
  1100. //
  1101. #define SdbpDoesFileExists(FilePath) RtlDoesFileExists_U(FullPath)
  1102. NTSTATUS
  1103. SdbpGUIDToUnicodeString(
  1104. IN GUID* pGuid,
  1105. OUT PUNICODE_STRING pUnicodeString
  1106. );
  1107. VOID
  1108. SdbpFreeUnicodeString(
  1109. PUNICODE_STRING pUnicodeString
  1110. );
  1111. #define GUID_TO_UNICODE_STRING(pGuid, pUnicodeString) \
  1112. SdbpGUIDToUnicodeString(pGuid, pUnicodeString)
  1113. #define FREE_GUID_STRING(pUnicodeString) \
  1114. SdbpFreeUnicodeString(pUnicodeString)
  1115. #ifdef KERNEL_MODE
  1116. NTSTATUS
  1117. SdbpUpcaseUnicodeStringToMultiByteN(
  1118. OUT LPSTR lpszDest, // dest buffer
  1119. IN DWORD dwSize, // size in characters
  1120. IN LPCWSTR lpszSrc // source
  1121. );
  1122. BOOL SdbpCreateUnicodeString(
  1123. PUNICODE_STRING pStr,
  1124. LPCWSTR lpwsz
  1125. );
  1126. BOOL
  1127. SdbpDoesFileExists_U(
  1128. LPCWSTR pwszPath
  1129. );
  1130. #define DOES_FILE_EXISTS_U(pwszPath) \
  1131. SdbpDoesFileExists_U(pwszPath)
  1132. #define UPCASE_UNICODETOMULTIBYTEN(szDest, dwDestSize, szSrc) \
  1133. SdbpUpcaseUnicodeStringToMultiByteN(szDest, dwDestSize, szSrc)
  1134. #else // not KERNEL_MODE code below
  1135. #define DOES_FILE_EXISTS_U(pwszPath) \
  1136. RtlDoesFileExists_U(pwszPath)
  1137. #define UPCASE_UNICODETOMULTIBYTEN(szDest, dwDestSize, szSrc) \
  1138. RtlUpcaseUnicodeToMultiByteN((szDest), \
  1139. (dwDestSize) * sizeof(*(szDest)), \
  1140. NULL, \
  1141. (WCHAR*)(szSrc), \
  1142. (wcslen((szSrc)) + 1) * sizeof(WCHAR))
  1143. #define FREE_TEMP_STRINGTABLE(pdb) \
  1144. RtlFreeUnicodeString(&pdb->ustrTempStringtable)
  1145. #define COPY_TEMP_STRINGTABLE(pdb, pszTempStringtable) \
  1146. RtlCreateUnicodeString(&pdb->ustrTempStringtable, pszTempStringtable)
  1147. void
  1148. SdbpGetCurrentTime(
  1149. LPSYSTEMTIME lpTime
  1150. );
  1151. BOOL
  1152. SdbpBuildUserKeyPath(
  1153. IN LPCWSTR pwszPath,
  1154. OUT PUNICODE_STRING puserKeyPath
  1155. );
  1156. #endif // KERNEL_MODE
  1157. //
  1158. // Convert unicode char to upper case
  1159. //
  1160. #define UPCASE_CHAR(ch) RtlUpcaseUnicodeChar((ch))
  1161. //
  1162. // String cache which does not exist in unicode
  1163. //
  1164. #define CLEANUP_STRING_CACHE_READ(pdb)
  1165. #define SDB_BREAK_POINT() DbgBreakPoint()
  1166. #else // WIN32A_MODE
  1167. #define IS_MEMORY_EQUAL(p1, p2, Size) (memcmp((p1), (p2), (Size)) == 0)
  1168. //
  1169. // From Win32Base.c
  1170. //
  1171. LPSTR
  1172. SdbpFastUnicodeToAnsi(
  1173. IN PDB pdb,
  1174. IN LPCWSTR pwszSrc,
  1175. IN TAG_TYPE ttTag,
  1176. IN DWORD dwRef
  1177. );
  1178. BOOL
  1179. SdbpReadStringToAnsi(
  1180. PDB pdb,
  1181. TAGID tiWhich,
  1182. LPSTR pszBuffer,
  1183. DWORD dwBufferSize);
  1184. #define CONVERT_STRINGPTR(pdb, pwszSrc, tagType, srWhich) \
  1185. SdbpFastUnicodeToAnsi(pdb, (WCHAR*)pwszSrc, tagType, (DWORD)srWhich)
  1186. #define READ_STRING(pdb, tiWhich, pwszBuffer, dwBufferSize) \
  1187. (SdbpReadStringToAnsi((pdb), (tiWhich), (pwszBuffer), (dwBufferSize)))
  1188. BOOL
  1189. SdbpDoesFileExists(
  1190. LPCTSTR pszFilePath
  1191. );
  1192. #define UPCASE_CHAR(ch) _totupper((ch))
  1193. #define UPCASE_UNICODETOMULTIBYTEN(szDest, dwDestSize, szSrc) \
  1194. (_tcsncpy((szDest), (szSrc), (dwDestSize)), \
  1195. (szDest)[(dwDestSize) - 1] = 0, \
  1196. _tcsupr((szDest)), \
  1197. STATUS_SUCCESS)
  1198. #define FREE_LOCALDB_NAME(pSDBContext) \
  1199. { \
  1200. if (NULL != pSDBContext->pszPDBLocal) { \
  1201. SdbFree(pSDBContext->pszPDBLocal); \
  1202. pSDBContext->pszPDBLocal = NULL; \
  1203. } \
  1204. }
  1205. #define COPY_LOCALDB_NAME(pSDBContext, pszLocalDatabase) \
  1206. ((pSDBContext->pszPDBLocal = SdbpDuplicateString(pszLocalDatabase)), \
  1207. (NULL != pSDBContext->pszPDBLocal))
  1208. #define CLEANUP_STRING_CACHE_READ(pdb) \
  1209. { \
  1210. if (pdb->pHashStringTable != NULL) { \
  1211. HashFree(pdb->pHashStringTable); \
  1212. pdb->pHashStringTable = NULL; \
  1213. } \
  1214. \
  1215. if (pdb->pHashStringBody != NULL) { \
  1216. HashFree(pdb->pHashStringBody); \
  1217. pdb->pHashStringBody = NULL; \
  1218. } \
  1219. }
  1220. #define FREE_TEMP_STRINGTABLE(pdb) \
  1221. if (pdb->pszTempStringtable) { \
  1222. SdbFree(pdb->pszTempStringtable); \
  1223. pdb->pszTempStringtable = NULL; \
  1224. }
  1225. #define COPY_TEMP_STRINGTABLE(pdb, pszTempStringtable) \
  1226. ((pdb->pszTempStringtable = SdbpDuplicateString(pszTempStringtable)), \
  1227. (NULL != pdb->pszTempStringtable))
  1228. #define SDB_BREAK_POINT() DebugBreak()
  1229. #define GUID_TO_STRING SdbGUIDToString
  1230. #endif // WIN32A_MODE
  1231. BOOL
  1232. SdbpMapFile(
  1233. HANDLE hFile, // handle to the open file (this is done previously)
  1234. PIMAGEFILEDATA pImageData
  1235. );
  1236. BOOL
  1237. SdbpUnmapFile(
  1238. PIMAGEFILEDATA pImageData
  1239. );
  1240. BOOL
  1241. SdbpOpenAndMapFile(
  1242. IN LPCTSTR szPath,
  1243. OUT PIMAGEFILEDATA pImageData,
  1244. IN PATH_TYPE ePathType
  1245. );
  1246. BOOL
  1247. SdbpUnmapAndCloseFile(
  1248. PIMAGEFILEDATA pImageData
  1249. );
  1250. NTSTATUS
  1251. SdbpGetEnvVar(
  1252. IN LPCTSTR pEnvironment,
  1253. IN LPCTSTR pszVariableName,
  1254. OUT LPTSTR pszVariableValue,
  1255. OUT LPDWORD pdwBufferSize);
  1256. LPTSTR HashAddStringByRef(PSTRHASH pHash, LPCTSTR szString, STRINGREF srString);
  1257. LPTSTR HashFindStringByRef(PSTRHASH pHash, STRINGREF srString);
  1258. /////////////////////////////////////////////////////////////////////////////////
  1259. //
  1260. // Private versions of functions to check for resources...
  1261. // found in ntver.c
  1262. //
  1263. BOOL
  1264. SdbpVerQueryValue(
  1265. const LPVOID pb,
  1266. LPVOID lpSubBlockX, // can be only unicode
  1267. LPVOID* lplpBuffer,
  1268. PUINT puLen
  1269. );
  1270. BOOL
  1271. SdbpGetFileVersionInformation(
  1272. IN PIMAGEFILEDATA pImageData, // we assume that the file has been mapped in for other purposes
  1273. OUT LPVOID* ppVersionInfo, // receives pointer to the (allocated) version resource
  1274. OUT VS_FIXEDFILEINFO** ppFixedVersionInfo // receives pointer to fixed version info
  1275. );
  1276. BOOL
  1277. SdbpGetModuleType( // retrieve module type
  1278. OUT LPDWORD lpdwModuleType, // OUT - module type
  1279. IN PIMAGEFILEDATA pImageData // IN - image data
  1280. );
  1281. BOOL
  1282. SdbpCreateSearchDBContext(
  1283. PSEARCHDBCONTEXT pContext,
  1284. LPCTSTR szPath,
  1285. LPCTSTR szModuleName,
  1286. LPCTSTR pEnvironment
  1287. );
  1288. DWORD
  1289. SdbpSearchDB(
  1290. IN HSDB hSDB,
  1291. IN PDB pdb, // pdb to search in
  1292. IN TAG tiSearchTag, // OPTIONAL - target tag (TAG_EXE or TAG_APPHELP_EXE)
  1293. IN PSEARCHDBCONTEXT pContext,
  1294. OUT TAGID* ptiExes, // caller needs to provide array of size SDB_MAX_EXES
  1295. OUT GUID* pLastExeGUID,
  1296. OUT DWORD* pLastExeFlags,
  1297. IN OUT PMATCHMODE pMatchMode // reason why we stopped scanning
  1298. );
  1299. void
  1300. SdbpReleaseSearchDBContext(
  1301. PSEARCHDBCONTEXT pContext
  1302. );
  1303. //
  1304. // this macro is used to retrieve ulonglong from the index
  1305. //
  1306. //
  1307. #if defined(_WIN64)
  1308. #define READ_INDEX_KEY(pIndexRecord, iIndex, pullKey) \
  1309. RtlMoveMemory((pullKey), &pIndexRecord[iIndex].ullKey, sizeof(*(pullKey)))
  1310. #else
  1311. #define READ_INDEX_KEY(pIndexRecord, iIndex, pullKey) \
  1312. *pullKey = pIndexRecord[iIndex].ullKey
  1313. #endif
  1314. #define READ_INDEX_KEY_VAL(pIndexRecord, iIndex, pullKey) \
  1315. ( READ_INDEX_KEY(pIndexRecord, iIndex, pullKey), *(pullKey) )
  1316. //
  1317. // this macro is used to allocate cheap pointer on the stack
  1318. //
  1319. #if DBG | defined(KERNEL_MODE) | defined(_WIN64)
  1320. #define STACK_ALLOC(ptrVar, nSize) \
  1321. { \
  1322. PVOID* ppVar = (PVOID*)&(ptrVar); \
  1323. *ppVar = SdbAlloc(nSize); \
  1324. }
  1325. #define STACK_FREE(pMemory) \
  1326. SdbFree(pMemory)
  1327. #else // hack-routine to reset the stack after an overflow
  1328. //
  1329. // this routine is a replica of a _resetstkoflw which lives in the crt
  1330. // crtw32\heap\resetstk.c
  1331. //
  1332. VOID
  1333. SdbResetStackOverflow(
  1334. VOID
  1335. );
  1336. //
  1337. // HACK ALERT
  1338. //
  1339. // The code below works because when we hit a stack overflow - we catch the exception
  1340. // and subsequently fix the stack up using a crt routine
  1341. //
  1342. #define STACK_ALLOC(ptrVar, nSize) \
  1343. __try { \
  1344. PVOID* ppVar = (PVOID*)&(ptrVar); \
  1345. *ppVar = _alloca(nSize); \
  1346. } __except (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW ? \
  1347. EXCEPTION_EXECUTE_HANDLER:EXCEPTION_CONTINUE_SEARCH) { \
  1348. (ptrVar) = NULL; \
  1349. } \
  1350. \
  1351. if (ptrVar == NULL) { \
  1352. SdbResetStackOverflow(); \
  1353. }
  1354. #define STACK_FREE(pMemory)
  1355. #endif
  1356. LPTSTR
  1357. SdbpDuplicateString(
  1358. LPCTSTR pszSrc);
  1359. #define FDA_FILESIZE 0x00000001
  1360. BOOL
  1361. SdbpQueryFileDirectoryAttributes(
  1362. LPCTSTR FilePath,
  1363. PFILEDIRECTORYATTRIBUTES pFileDirectoryAttributes
  1364. );
  1365. //
  1366. // Magic fileinfo signature
  1367. //
  1368. #define FILEINFO_MAGIC 0xA4C0FFEE
  1369. WCHAR*
  1370. DuplicateUnicodeString(
  1371. IN PUNICODE_STRING pStr,
  1372. IN PUSHORT pLength OPTIONAL
  1373. ); // pLength is an allocated length
  1374. LPWSTR
  1375. StringToUnicodeString(
  1376. IN LPCSTR pszSrc
  1377. );
  1378. //
  1379. // defined for uni/non-uni separately
  1380. //
  1381. BOOL
  1382. SdbpGet16BitDescription(
  1383. LPTSTR* ppszDescription,
  1384. PIMAGEFILEDATA pImageData
  1385. );
  1386. BOOL
  1387. SdbpGet16BitModuleName(
  1388. LPTSTR* ppszModuleName,
  1389. PIMAGEFILEDATA pImageData
  1390. );
  1391. //
  1392. // in attributes.c
  1393. //
  1394. BOOL
  1395. SdbpQuery16BitDescription(
  1396. LPSTR szBuffer, // min length -- 256 chars !
  1397. PIMAGEFILEDATA pImageData
  1398. );
  1399. BOOL
  1400. SdbpQuery16BitModuleName(
  1401. LPSTR szBuffer, // min length -- 256 chars !
  1402. PIMAGEFILEDATA pImageData
  1403. );
  1404. LPCTSTR
  1405. SdbpModuleTypeToString(
  1406. DWORD dwModuleType
  1407. );
  1408. //
  1409. // in index.c
  1410. //
  1411. BOOL
  1412. SdbpPatternMatch(
  1413. IN LPCTSTR pszPattern,
  1414. IN LPCTSTR pszTestString);
  1415. BOOL
  1416. SdbpPatternMatchAnsi(
  1417. IN LPCSTR pszPattern,
  1418. IN LPCSTR pszTestString);
  1419. //
  1420. // defined for uni/non-uni separately
  1421. //
  1422. //////////////////////////////////////////////////////////////////////////////////
  1423. //
  1424. // GetFileInfo
  1425. // 1. performs check on a file to determine if it exists
  1426. // 2. if it does exist -- it leaves a cache entry (creates a fileinfo struct)
  1427. // if it does NOT exist -- we leave no mention of it on record
  1428. // if bNoCache == TRUE the file is not entered into the cache
  1429. // caller must free the stucture using FreeFileData
  1430. //
  1431. // Parameters:
  1432. // tiMatch - IN - match id from the database, used temporary
  1433. // FilePath - IN - file path that we are to check
  1434. // bNoCache - IN - whether we should enter the file into cache
  1435. //
  1436. // returns:
  1437. // Pointer to internal data structure that should be used in
  1438. // subsequent calls to SdbpCheckAttribute or NULL if file was not available
  1439. //
  1440. PVOID
  1441. SdbGetFileInfo(
  1442. IN HSDB hSDB,
  1443. IN LPCTSTR pszFilePath,
  1444. IN HANDLE hFile OPTIONAL,
  1445. IN LPVOID pImageBase OPTIONAL,
  1446. IN DWORD dwImageSize OPTIONAL,
  1447. IN BOOL bNoCache
  1448. );
  1449. //
  1450. // in attributes.c
  1451. //
  1452. PFILEINFO
  1453. CreateFileInfo(
  1454. IN PSDBCONTEXT pContext,
  1455. IN LPCTSTR FullPath,
  1456. IN DWORD dwLength OPTIONAL, // length (in characters) of FullPath string
  1457. IN HANDLE hFile OPTIONAL, // file handle
  1458. IN LPVOID pImageBase OPTIONAL,
  1459. IN DWORD dwImageSize OPTIONAL,
  1460. IN BOOL bNoCache
  1461. );
  1462. PFILEINFO
  1463. FindFileInfo(
  1464. PSDBCONTEXT pContext,
  1465. LPCTSTR FilePath
  1466. );
  1467. // defined unicode and non-unicode
  1468. INT GetShimDbgLevel(VOID);
  1469. //
  1470. // from index.c
  1471. //
  1472. STRINGREF HashFindString(PSTRHASH pHash, LPCTSTR szString);
  1473. BOOL HashAddString(PSTRHASH pHash, LPCTSTR szString, STRINGREF srString);
  1474. BOOL
  1475. SdbpIsPathOnCdRom(
  1476. LPCTSTR pszPath
  1477. );
  1478. BOOL
  1479. SdbpBuildSignature(
  1480. LPCTSTR pszPath,
  1481. LPTSTR pszPathSigned
  1482. );
  1483. //
  1484. // in ntbase/win32base
  1485. //
  1486. DWORD
  1487. SdbpGetProcessorArchitecture(
  1488. VOID
  1489. );
  1490. VOID
  1491. SdbpGetOSSKU(
  1492. LPDWORD lpdwSKU,
  1493. LPDWORD lpdwSP
  1494. );
  1495. //
  1496. // in Attributes.c
  1497. //
  1498. BOOL
  1499. SdbpCheckRuntimePlatform(
  1500. IN PSDBCONTEXT pContext, // pointer to the database channel
  1501. IN LPCTSTR pszMatchingFile,
  1502. IN DWORD dwPlatformDB
  1503. );
  1504. //
  1505. // convenient define
  1506. //
  1507. #ifndef OFFSETOF
  1508. #define OFFSETOF offsetof
  1509. #endif
  1510. /* // Use this pragma below in conjunction with the commented block
  1511. // in the beginning of the file to compile with warning level 4
  1512. #pragma warning(pop)
  1513. */
  1514. #endif // __SDBP_H__