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.

799 lines
21 KiB

  1. #include "sfcp.h"
  2. #include "sfcfiles.h"
  3. #include <wchar.h>
  4. #define NOEXTAPI
  5. #include <wdbgexts.h>
  6. #undef DECLARE_API
  7. #ifdef __cplusplus
  8. #define CPPMOD extern "C"
  9. #else
  10. #define CPPMOD
  11. #endif
  12. #define DECLARE_API(s) \
  13. CPPMOD VOID \
  14. s( \
  15. HANDLE hCurrentProcess, \
  16. HANDLE hCurrentThread, \
  17. DWORD_PTR dwCurrentPc, \
  18. PWINDBG_EXTENSION_APIS lpExtensionApis, \
  19. LPSTR lpArgumentString \
  20. )
  21. #define INIT_API() { \
  22. ExtensionApis = *lpExtensionApis; \
  23. ExtensionCurrentProcess = hCurrentProcess; \
  24. }
  25. #define dprintf (ExtensionApis.lpOutputRoutine)
  26. #define GetExpression (ExtensionApis.lpGetExpressionRoutine)
  27. #define GetSymbol (ExtensionApis.lpGetSymbolRoutine)
  28. #define Disasm (ExtensionApis.lpDisasmRoutine)
  29. #define CheckControlC (ExtensionApis.lpCheckControlCRoutine)
  30. #define ReadMemory(a,b,c,d) \
  31. ((ExtensionApis.nSize == sizeof(WINDBG_OLD_EXTENSION_APIS)) ? \
  32. ReadProcessMemory( ExtensionCurrentProcess, (LPCVOID)(a), (b), (c), (d) ) \
  33. : ExtensionApis.lpReadProcessMemoryRoutine( (ULONG_PTR)(a), (b), (c), ((DWORD *)d) ))
  34. #define WriteMemory(a,b,c,d) \
  35. ((ExtensionApis.nSize == sizeof(WINDBG_OLD_EXTENSION_APIS)) ? \
  36. WriteProcessMemory( ExtensionCurrentProcess, (LPVOID)(a), (LPVOID)(b), (c), (d) ) \
  37. : ExtensionApis.lpWriteProcessMemoryRoutine( (ULONG_PTR)(a), (LPVOID)(b), (c), ((DWORD *)d) ))
  38. #define Ioctl (ExtensionApis.lpIoctlRoutine)
  39. WINDBG_EXTENSION_APIS ExtensionApis;
  40. HANDLE ExtensionCurrentProcess;
  41. PWSTR
  42. MultiByteToUnicode(
  43. IN PCSTR String,
  44. IN UINT Codepage
  45. )
  46. /*++
  47. Routine Description:
  48. Convert a string to unicode.
  49. Arguments:
  50. String - supplies string to be converted.
  51. Codepage - supplies codepage to be used for the conversion.
  52. Return Value:
  53. NULL if string could not be converted (out of memory or invalid cp)
  54. Caller can free buffer with MyFree().
  55. --*/
  56. {
  57. UINT BytesIn8BitString;
  58. UINT CharsInUnicodeString;
  59. PWSTR UnicodeString;
  60. BytesIn8BitString = lstrlenA(String) + 1;
  61. //
  62. // Allocate maximally sized buffer.
  63. // If every character is a single-byte character,
  64. // then the buffer needs to be twice the size
  65. // as the 8bit string. Otherwise it might be smaller,
  66. // as some characters are 2 bytes in their unicode and
  67. // 8bit representations.
  68. //
  69. UnicodeString = malloc(BytesIn8BitString * sizeof(WCHAR));
  70. if(UnicodeString == NULL) {
  71. return(NULL);
  72. }
  73. //
  74. // Perform the conversion.
  75. //
  76. CharsInUnicodeString = MultiByteToWideChar(
  77. Codepage,
  78. MB_PRECOMPOSED,
  79. String,
  80. BytesIn8BitString,
  81. UnicodeString,
  82. BytesIn8BitString
  83. );
  84. if(CharsInUnicodeString == 0) {
  85. free(UnicodeString);
  86. return(NULL);
  87. }
  88. return(UnicodeString);
  89. }
  90. void
  91. dump_SFC_REGISTRY_VALUE(
  92. PSFC_REGISTRY_VALUE srv,
  93. DWORD_PTR Addr
  94. )
  95. {
  96. SIZE_T cb;
  97. WCHAR buf[512];
  98. dprintf( "SFC_REGISTRY_VALUE at %p\n", Addr );
  99. dprintf( "\tEntry.Flink = 0x%08x\n", srv->Entry.Flink );
  100. dprintf( "\tEntry.Blink = 0x%08x\n", srv->Entry.Blink );
  101. ReadMemory( srv->FileName.Buffer, buf, srv->FileName.Length+sizeof(WCHAR), &cb);
  102. dprintf( "\tFileName = %ws\n", buf );
  103. ReadMemory( srv->DirName.Buffer, buf, srv->DirName.Length+sizeof(WCHAR), &cb);
  104. dprintf( "\tDirName = %ws\n", buf );
  105. ReadMemory( srv->FullPathName.Buffer, buf, srv->FullPathName.Length+sizeof(WCHAR), &cb);
  106. dprintf( "\tFullPathName = %ws\n", buf );
  107. ReadMemory( srv->InfName.Buffer, buf, srv->FileName.Length+sizeof(WCHAR), &cb);
  108. dprintf( "\tInfName = %ws\n", srv->InfName );
  109. ReadMemory( srv->SourceFileName.Buffer, buf, srv->SourceFileName.Length+sizeof(WCHAR), &cb);
  110. dprintf( "\tSourceFileName = %ws\n", srv->SourceFileName );
  111. dprintf( "\tDirHandle = 0x%08x\n", srv->DirHandle );
  112. //dprintf( "\tFlags = 0x%08x\n", srv->IgnoreNextChange );
  113. }
  114. void
  115. dump_IMAGE_VALIDATION_DATA(
  116. PIMAGE_VALIDATION_DATA ivd
  117. )
  118. {
  119. dprintf( "DllVersion = 0x%I64x\n", ivd->DllVersion );
  120. dprintf( "DllCheckSum = 0x%08x\n", ivd->DllCheckSum );
  121. dprintf( "SignatureValid = %s\n", ivd->SignatureValid ? "true" : "false" );
  122. dprintf( "FilePresent = %s\n", ivd->FilePresent ? "true" : "false" );
  123. }
  124. void
  125. dump_COMPLETE_VALIDATION_DATA(
  126. PCOMPLETE_VALIDATION_DATA cvd
  127. )
  128. {
  129. dprintf( "*Original* = 0x%08x\n", &cvd->Original );
  130. dump_IMAGE_VALIDATION_DATA( &cvd->Original );
  131. dprintf( "*Cache* = 0x%08x\n", &cvd->Cache );
  132. dump_IMAGE_VALIDATION_DATA( &cvd->Cache );
  133. dprintf( "*New* = 0x%08x\n", &cvd->New );
  134. dump_IMAGE_VALIDATION_DATA( &cvd->New );
  135. dprintf( "RestoreFromReal = %s\n", cvd->RestoreFromReal ? "true" : "false" );
  136. dprintf( "RestoreFromCache = %s\n", cvd->RestoreFromCache ? "true" : "false" );
  137. dprintf( "RestoreFromMedia = %s\n", cvd->RestoreFromMedia ? "true" : "false" );
  138. dprintf( "NotifyUser = %s\n", cvd->NotifyUser ? "true" : "false" );
  139. dprintf( "BadCacheEntry = %s\n", cvd->BadCacheEntry ? "true" : "false" );
  140. }
  141. void
  142. dump_RESTORE_QUEUE(
  143. PRESTORE_QUEUE rq,
  144. DWORD_PTR Addr
  145. )
  146. {
  147. dprintf( "RESTORE_QUEUE at %p\n", Addr );
  148. dprintf( "FileQueue = %p\n", rq->FileQueue );
  149. dprintf( "QueueCount = %d\n", rq->QueueCount );
  150. dprintf( "RestoreInProgress = %s\n", rq->RestoreInProgress ? "true" : "false" );
  151. dprintf( "RestoreComplete = %s\n", rq->RestoreComplete ? "true" : "false" );
  152. dprintf( "RestoreStatus = %s\n", rq->RestoreStatus ? "true" : "false" );
  153. dprintf( "LastErrorCode = %d (0x%08x)\n", rq->LastErrorCode, rq->LastErrorCode );
  154. dprintf( "WorkerThreadHandle = %d\n", rq->WorkerThreadHandle );
  155. }
  156. void
  157. dump_VALIDATION_REQUEST_DATA(
  158. PVALIDATION_REQUEST_DATA vrd,
  159. DWORD_PTR Addr
  160. )
  161. {
  162. SIZE_T cb;
  163. SFC_REGISTRY_VALUE RegVal;
  164. dprintf( "**VALIDATION_REQUEST_DATA at address = 0x%p**\n", Addr );
  165. #if DBG
  166. if (vrd->Signature != 0x69696969) {
  167. dprintf( "**** invalid queue entry, signature does not match\n" );
  168. return;
  169. }
  170. #endif
  171. dprintf( "\tEntry.Flink = 0x%08x\n", vrd->Entry.Flink );
  172. dprintf( "\tEntry.Blink = 0x%08x\n", vrd->Entry.Blink );
  173. dprintf( "\tImageValData = 0x%08x\n", &vrd->ImageValData );
  174. dump_COMPLETE_VALIDATION_DATA( &vrd->ImageValData );
  175. dprintf( "\tRegVal = 0x%08x\n", vrd->RegVal );
  176. ReadMemory( vrd->RegVal, &RegVal, sizeof(SFC_REGISTRY_VALUE), &cb);
  177. dump_SFC_REGISTRY_VALUE( &RegVal, (DWORD_PTR)vrd->RegVal );
  178. dprintf( "\tChangeType = %d\n", vrd->ChangeType );
  179. dprintf( "\tCopyCompleted = %s\n", vrd->CopyCompleted ? "true" : "false" );
  180. dprintf( "\tWin32Error = %d (0x%08x)\n", vrd->Win32Error, vrd->Win32Error );
  181. dprintf( "\tFlags = 0x%08x\n", vrd->Flags );
  182. dprintf( "\tRetryCount = 0x%08x\n", vrd->RetryCount );
  183. dprintf( "\tSyncOnly = %s\n", vrd->SyncOnly ? "true" : "false" );
  184. }
  185. void
  186. dump_PROTECT_FILE_ENTRY(
  187. PPROTECT_FILE_ENTRY Entry,
  188. DWORD_PTR Addr
  189. )
  190. {
  191. WCHAR SourceFileBuffer[MAX_PATH];
  192. WCHAR DestFileBuffer[MAX_PATH];
  193. WCHAR InfNameBuffer[MAX_PATH];
  194. SIZE_T cb;
  195. if (Entry->SourceFileName) {
  196. ReadMemory( Entry->SourceFileName, SourceFileBuffer, sizeof(SourceFileBuffer), &cb);
  197. }else {
  198. SourceFileBuffer[0] = L'\0';
  199. }
  200. if (Entry->FileName) {
  201. ReadMemory( Entry->FileName, DestFileBuffer, sizeof(DestFileBuffer), &cb);
  202. }else {
  203. DestFileBuffer[0] = L'\0';
  204. }
  205. if (Entry->InfName) {
  206. ReadMemory( Entry->InfName, InfNameBuffer, sizeof(InfNameBuffer), &cb);
  207. }else {
  208. InfNameBuffer[0] = L'\0';
  209. }
  210. dprintf( " PROTECT_FILE_ENTRY at %p\n", Addr );
  211. dprintf( " \tSourceFileName = %S\n" , SourceFileBuffer[0] ? SourceFileBuffer : L"[Same as target name]" );
  212. dprintf( " \tFileName = %S\n" , DestFileBuffer );
  213. dprintf( " \tInfName = %S\n" , InfNameBuffer[0] ? InfNameBuffer : L"[None, default to layout.inf]" );
  214. }
  215. BOOL
  216. DoesProtFileEntryMatch(
  217. PPROTECT_FILE_ENTRY Entry,
  218. DWORD_PTR Addr,
  219. PCWSTR FileName
  220. )
  221. {
  222. WCHAR SourceFileBuffer[MAX_PATH];
  223. WCHAR DestFileBuffer[MAX_PATH];
  224. WCHAR InfNameBuffer[MAX_PATH];
  225. DWORD count;
  226. PCWSTR p;
  227. SIZE_T cb;
  228. PCWSTR a[3] = { SourceFileBuffer, DestFileBuffer, InfNameBuffer } ;
  229. if (Entry->SourceFileName) {
  230. ReadMemory( Entry->SourceFileName, SourceFileBuffer, sizeof(SourceFileBuffer), &cb);
  231. }else {
  232. SourceFileBuffer[0] = L'\0';
  233. }
  234. if (Entry->FileName) {
  235. ReadMemory( Entry->FileName, DestFileBuffer, sizeof(DestFileBuffer), &cb);
  236. }else {
  237. DestFileBuffer[0] = L'\0';
  238. }
  239. if (Entry->InfName) {
  240. ReadMemory( Entry->InfName, InfNameBuffer, sizeof(InfNameBuffer), &cb);
  241. }else {
  242. InfNameBuffer[0] = L'\0';
  243. }
  244. for (count = 0; count < 3; count++) {
  245. p = wcsrchr( a[count], L'\\' );
  246. if (p) {
  247. p += 1;
  248. if (_wcsicmp(p, FileName)== 0) {
  249. return(TRUE);
  250. }
  251. }
  252. }
  253. return(FALSE);
  254. }
  255. BOOL
  256. DoesRegEntryMatch(
  257. PSFC_REGISTRY_VALUE Entry,
  258. DWORD_PTR Addr,
  259. PCWSTR FileName
  260. )
  261. {
  262. WCHAR Buffer[MAX_PATH];
  263. DWORD count;
  264. PCWSTR p;
  265. SIZE_T cb;
  266. PUNICODE_STRING a[5];
  267. a[0] = &Entry->FileName;
  268. a[1] = &Entry->DirName;
  269. a[2] = &Entry->FullPathName;
  270. a[3] = &Entry->InfName;
  271. a[4] = &Entry->SourceFileName;
  272. for (count = 0; count < 5; count++) {
  273. if (a[count]->Buffer) {
  274. ReadMemory( a[count]->Buffer, Buffer, sizeof(Buffer), &cb);
  275. }
  276. p = wcsrchr( Buffer, L'\\' );
  277. if (p) {
  278. p += 1;
  279. } else {
  280. p = Buffer;
  281. }
  282. if (_wcsicmp(p, FileName)== 0) {
  283. return(TRUE);
  284. }
  285. }
  286. return(FALSE);
  287. }
  288. DECLARE_API( help )
  289. {
  290. INIT_API();
  291. dprintf( "WFP debugger extension commands:\n" );
  292. dprintf( "dumpq - dump validation queue\n" );
  293. dprintf( "dumpsettings - dump global WFP settings\n" );
  294. dprintf( "isprotfile [filename] - search for a particular protected file in the list\n" );
  295. dprintf( "isprotfile [list address] [list count address] [filename] - search for a particular protected file in the list\n" );
  296. dprintf( "protfile - list all protected files in list\n" );
  297. dprintf( "protfile - [list address] [list count address] list all protected files in list\n" );
  298. }
  299. DECLARE_API( dumpq )
  300. {
  301. DWORD_PTR addr;
  302. SIZE_T cb;
  303. LIST_ENTRY Next;
  304. VALIDATION_REQUEST_DATA vrd;
  305. INIT_API();
  306. addr = GetExpression( "SfcErrorQueue" );
  307. if (!addr) {
  308. dprintf("couldn't get address");
  309. return;
  310. }
  311. dprintf( "SfcErrorQueue address=0x%p\n", addr );
  312. ReadMemory( addr, &Next, sizeof(Next), &cb);
  313. if (Next.Flink == (PVOID)addr) {
  314. dprintf( "queue is empty\n" );
  315. return;
  316. }
  317. do {
  318. ReadMemory( Next.Flink, &vrd, sizeof(VALIDATION_REQUEST_DATA), &cb);
  319. dump_VALIDATION_REQUEST_DATA( &vrd, (DWORD_PTR)Next.Flink );
  320. Next.Flink = vrd.Entry.Flink;
  321. if (Next.Flink != (PVOID)addr) {
  322. dprintf( "\n******************************************\n\n" );
  323. }
  324. if (CheckControlC() ) {
  325. dprintf( "\nInterrupted\n\n" );
  326. break;
  327. }
  328. } while (Next.Flink != (PVOID)addr);
  329. }
  330. DECLARE_API( dumpsettings )
  331. {
  332. DWORD_PTR addr;
  333. SIZE_T cb;
  334. DWORD val;
  335. INIT_API();
  336. addr = GetExpression( "SFCDisable" );
  337. if (!addr) {
  338. dprintf("couldn't get address");
  339. return;
  340. }
  341. ReadMemory( addr, &val, sizeof(DWORD), &cb);
  342. dprintf( "SFCDisable = %d\n", val );
  343. }
  344. DECLARE_API( dumpregval )
  345. {
  346. DWORD_PTR addr;
  347. SIZE_T cb;
  348. SFC_REGISTRY_VALUE regval;
  349. INIT_API();
  350. while (*lpArgumentString == ' ') {
  351. lpArgumentString++;
  352. }
  353. if (*lpArgumentString) {
  354. addr = GetExpression( lpArgumentString );
  355. } else {
  356. dprintf("bogus usage\n");
  357. return;
  358. }
  359. if (!addr) {
  360. dprintf("couldn't get address");
  361. return;
  362. }
  363. ReadMemory( addr, &regval, sizeof(SFC_REGISTRY_VALUE), &cb);
  364. dump_SFC_REGISTRY_VALUE( &regval, (DWORD_PTR)addr );
  365. return;
  366. }
  367. DECLARE_API( dumprq )
  368. {
  369. DWORD_PTR addr;
  370. SIZE_T cb;
  371. RESTORE_QUEUE rq;
  372. INIT_API();
  373. while (*lpArgumentString == ' ') {
  374. lpArgumentString++;
  375. }
  376. if (*lpArgumentString) {
  377. addr = GetExpression( lpArgumentString );
  378. } else {
  379. dprintf("bogus usage\n");
  380. return;
  381. }
  382. if (!addr) {
  383. dprintf("couldn't get address");
  384. return;
  385. }
  386. ReadMemory( addr, &rq, sizeof(RESTORE_QUEUE), &cb);
  387. dump_RESTORE_QUEUE( &rq, addr );
  388. return;
  389. }
  390. DECLARE_API( dumpvrd )
  391. {
  392. DWORD_PTR addr;
  393. SIZE_T cb;
  394. VALIDATION_REQUEST_DATA vrd;
  395. INIT_API();
  396. while (*lpArgumentString == ' ') {
  397. lpArgumentString++;
  398. }
  399. if (*lpArgumentString) {
  400. addr = GetExpression( lpArgumentString );
  401. } else {
  402. dprintf("bogus usage\n");
  403. return;
  404. }
  405. if (!addr) {
  406. dprintf("couldn't get address");
  407. return;
  408. }
  409. ReadMemory( addr, &vrd, sizeof(VALIDATION_REQUEST_DATA), &cb);
  410. dump_VALIDATION_REQUEST_DATA( &vrd, addr );
  411. return;
  412. }
  413. DECLARE_API( protfile )
  414. {
  415. DWORD_PTR addrNext, addrTotal;
  416. SIZE_T cb;
  417. PROTECT_FILE_ENTRY Next;
  418. ULONG Total;
  419. ULONG Current;
  420. INIT_API();
  421. while (*lpArgumentString == ' ') {
  422. lpArgumentString++;
  423. }
  424. if (*lpArgumentString) {
  425. addrNext = GetExpression( lpArgumentString );
  426. while (*lpArgumentString && (*lpArgumentString != ' ') ) {
  427. lpArgumentString++;
  428. }
  429. while (*lpArgumentString == ' ') {
  430. lpArgumentString++;
  431. }
  432. if (*lpArgumentString) {
  433. addrTotal = GetExpression( lpArgumentString );
  434. } else {
  435. dprintf("bogus usage\n");
  436. return;
  437. }
  438. }
  439. else {
  440. addrNext = GetExpression( "sfc!Tier2Files" );
  441. addrTotal = GetExpression( "sfc!CountTier2Files" );
  442. }
  443. if (!addrTotal || !addrNext) {
  444. dprintf("couldn't get address");
  445. return;
  446. }
  447. ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
  448. ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
  449. dprintf( "Tier2Files: address=0x%p Total=%d\n", addrNext, Total );
  450. Current = 0;
  451. while (Current < Total) {
  452. dump_PROTECT_FILE_ENTRY( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
  453. ReadMemory( addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)), &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
  454. Current += 1;
  455. if ( CheckControlC() ) {
  456. dprintf( "\nInterrupted\n\n" );
  457. break;
  458. }
  459. }
  460. }
  461. DECLARE_API( isprotfile )
  462. {
  463. DWORD_PTR addrNext, addrTotal;
  464. PCSTR FileName;
  465. SIZE_T cb;
  466. PROTECT_FILE_ENTRY Next;
  467. ULONG Total;
  468. ULONG Current;
  469. BOOL FoundMatch = FALSE;
  470. PCWSTR FileNameW;
  471. INIT_API();
  472. while (*lpArgumentString == ' ') {
  473. lpArgumentString++;
  474. }
  475. if (*lpArgumentString) {
  476. FileName = lpArgumentString;
  477. addrNext = GetExpression( lpArgumentString );
  478. while (*lpArgumentString && (*lpArgumentString != ' ') ) {
  479. lpArgumentString++;
  480. }
  481. while (*lpArgumentString == ' ') {
  482. lpArgumentString++;
  483. }
  484. if (*lpArgumentString) {
  485. addrTotal = GetExpression( lpArgumentString );
  486. } else {
  487. addrNext = GetExpression( "sfc!Tier2Files" );
  488. addrTotal = GetExpression( "sfc!CountTier2Files" );
  489. goto doit;
  490. }
  491. while (*lpArgumentString && (*lpArgumentString != ' ') ) {
  492. lpArgumentString++;
  493. }
  494. while (*lpArgumentString == ' ') {
  495. lpArgumentString++;
  496. }
  497. if (*lpArgumentString) {
  498. FileName = lpArgumentString;
  499. } else {
  500. dprintf("bogus usage\n");
  501. return;
  502. }
  503. } else {
  504. dprintf("bogus usage\n");
  505. return;
  506. }
  507. doit:
  508. if (!addrTotal || !addrNext) {
  509. dprintf("couldn't get address");
  510. return;
  511. }
  512. ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
  513. ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
  514. FileNameW = MultiByteToUnicode( FileName, CP_ACP );
  515. if (!FileNameW) {
  516. dprintf("Error: couldn't convert filename to unicode string\n");
  517. return;
  518. }
  519. Current = 0;
  520. while (Current < Total) {
  521. if (DoesProtFileEntryMatch( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)),FileNameW )) {
  522. dump_PROTECT_FILE_ENTRY( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
  523. FoundMatch = TRUE;
  524. }
  525. ReadMemory( addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)), &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
  526. Current += 1;
  527. if ( CheckControlC() ) {
  528. dprintf( "\nInterrupted\n\n" );
  529. break;
  530. }
  531. }
  532. if (!FoundMatch) {
  533. dprintf( "Couldn't find %s in list\n", FileName );
  534. }
  535. free((PVOID)FileNameW);
  536. }
  537. DECLARE_API( regvals )
  538. {
  539. DWORD_PTR addrNext, addrTotal;
  540. SIZE_T cb;
  541. SFC_REGISTRY_VALUE Next;
  542. ULONG Total;
  543. ULONG Current;
  544. INIT_API();
  545. addrNext = GetExpression( "sfc!SfcProtectedDllsList" );
  546. addrTotal = GetExpression( "sfc!SfcProtectedDllCount" );
  547. if (!addrNext || ! addrTotal) {
  548. dprintf("Error: couldn't resolve sfc!SfcProtectedDllsList and sfc!SfcProtectedDllCount\n");
  549. return;
  550. }
  551. ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
  552. ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
  553. dprintf( "SfcProtectedDllsList: address=0x%p Total=%d\n", addrNext, Total );
  554. Current = 0;
  555. while (Current < Total) {
  556. dump_SFC_REGISTRY_VALUE( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
  557. ReadMemory( addrNext+(Current*sizeof(SFC_REGISTRY_VALUE)), &Next, sizeof(SFC_REGISTRY_VALUE), &cb);
  558. Current += 1;
  559. if ( CheckControlC() ) {
  560. dprintf( "\nInterrupted\n\n" );
  561. break;
  562. }
  563. }
  564. }
  565. DECLARE_API( getregval )
  566. {
  567. DWORD_PTR addrNext, addrTotal;
  568. PCSTR FileName;
  569. SIZE_T cb;
  570. SFC_REGISTRY_VALUE Next;
  571. ULONG Total;
  572. ULONG Current;
  573. BOOL FoundMatch = FALSE;
  574. PCWSTR FileNameW;
  575. INIT_API();
  576. while (*lpArgumentString == ' ') {
  577. lpArgumentString++;
  578. }
  579. if (*lpArgumentString) {
  580. FileName = lpArgumentString;
  581. } else {
  582. dprintf("bogus usage\n");
  583. return;
  584. }
  585. addrNext = GetExpression( "sfc!SfcProtectedDllsList" );
  586. addrTotal = GetExpression( "sfc!SfcProtectedDllCount" );
  587. if (!addrNext || ! addrTotal) {
  588. dprintf("Error: couldn't resolve sfc!SfcProtectedDllsList and sfc!SfcProtectedDllCount\n");
  589. return;
  590. }
  591. ReadMemory( addrNext, &Next, sizeof(PROTECT_FILE_ENTRY), &cb);
  592. ReadMemory( addrTotal, &Total, sizeof(ULONG), &cb);
  593. FileNameW = MultiByteToUnicode( FileName, CP_ACP );
  594. if (!FileNameW) {
  595. dprintf("Error: couldn't convert filename to unicode string\n");
  596. return;
  597. }
  598. Current = 0;
  599. while (Current < Total) {
  600. if (DoesRegEntryMatch( &Next, addrNext+(Current*sizeof(SFC_REGISTRY_VALUE)),FileNameW )) {
  601. dump_SFC_REGISTRY_VALUE( &Next, addrNext+(Current*sizeof(PROTECT_FILE_ENTRY)) );
  602. FoundMatch = TRUE;
  603. }
  604. ReadMemory( addrNext+(Current*sizeof(SFC_REGISTRY_VALUE)), &Next, sizeof(SFC_REGISTRY_VALUE), &cb);
  605. Current += 1;
  606. if ( CheckControlC() ) {
  607. dprintf( "\nInterrupted\n\n" );
  608. break;
  609. }
  610. }
  611. if (!FoundMatch) {
  612. dprintf( "Couldn't find %s in list\n", FileName );
  613. }
  614. free((PVOID)FileNameW);
  615. }