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

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