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.

885 lines
21 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. heap.c
  5. Abstract:
  6. This function contains the default ntsd debugger extensions
  7. Author:
  8. Bob Day (bobday) 29-Feb-1992 Grabbed standard header
  9. Revision History:
  10. Neil Sandlin (NeilSa) 15-Jan-1996 Merged with vdmexts
  11. Added command line parsing
  12. --*/
  13. #include <precomp.h>
  14. #pragma hdrstop
  15. VDMCONTEXT ThreadContext;
  16. PVOID LdtAddress = NULL;
  17. BOOL
  18. WINAPI
  19. ReadProcessMem(
  20. LPVOID lpBaseAddress,
  21. LPVOID lpBuffer,
  22. DWORD nSize
  23. )
  24. {
  25. return ReadProcessMemory( hCurrentProcess, lpBaseAddress, lpBuffer, nSize, NULL );
  26. }
  27. BOOL
  28. WINAPI
  29. WriteProcessMem(
  30. LPVOID lpBaseAddress,
  31. LPVOID lpBuffer,
  32. DWORD nSize
  33. )
  34. {
  35. return WriteProcessMemory( hCurrentProcess, lpBaseAddress, lpBuffer, nSize, NULL );
  36. }
  37. #ifndef i386
  38. //
  39. // The following two routines implement the very funky way that we
  40. // have to get register values on the 486 emulator.
  41. //
  42. ULONG
  43. GetRegValue(
  44. NT_CPU_REG reg,
  45. BOOL bInNano,
  46. ULONG UMask
  47. )
  48. {
  49. if (bInNano) {
  50. return(ReadDwordSafe(reg.nano_reg));
  51. } else if (UMask & reg.universe_8bit_mask) {
  52. return (ReadDwordSafe(reg.saved_reg) & 0xFFFFFF00 |
  53. ReadDwordSafe(reg.reg) & 0xFF);
  54. } else if (UMask & reg.universe_16bit_mask) {
  55. return (ReadDwordSafe(reg.saved_reg) & 0xFFFF0000 |
  56. ReadDwordSafe(reg.reg) & 0xFFFF);
  57. } else {
  58. return (ReadDwordSafe(reg.reg));
  59. }
  60. }
  61. ULONG
  62. GetEspValue(
  63. NT_CPU_INFO nt_cpu_info,
  64. BOOL bInNano
  65. )
  66. {
  67. if (bInNano) {
  68. return (ReadDwordSafe(nt_cpu_info.nano_esp));
  69. } else {
  70. if (ReadDwordSafe(nt_cpu_info.stack_is_big)) {
  71. return (ReadDwordSafe(nt_cpu_info.host_sp) -
  72. ReadDwordSafe(nt_cpu_info.ss_base));
  73. } else {
  74. return (ReadDwordSafe(nt_cpu_info.esp_sanctuary) & 0xFFFF0000 |
  75. (ReadDwordSafe(nt_cpu_info.host_sp) -
  76. ReadDwordSafe(nt_cpu_info.ss_base) & 0xFFFF));
  77. }
  78. }
  79. }
  80. #endif
  81. int
  82. GetContext(
  83. VDMCONTEXT* lpContext
  84. )
  85. /*
  86. GetContext
  87. This function fills in the specified context record with
  88. the content of the 16-bit registers. The return value is
  89. the mode (v86 or PROT) of the client.
  90. Note that on x86, if the machine is currently in the monitor,
  91. we have to pick up the values from the VdmTib and IntelMSW.
  92. */
  93. {
  94. #ifndef i386 //
  95. int mode;
  96. ULONG pTmp;
  97. NT_CPU_INFO nt_cpu_info;
  98. BOOL b;
  99. BOOL bInNano;
  100. ULONG UMask;
  101. #if 0
  102. DWORD MyEflags;
  103. #endif
  104. pTmp = (ULONG)EXPRESSION("ntvdm!nt_cpu_info");
  105. if ( pTmp ) {
  106. b = READMEM((LPVOID) pTmp, &nt_cpu_info, sizeof(NT_CPU_INFO));
  107. if ( !b ) {
  108. PRINTF("Could not read IntelRegisters context out of process\n");
  109. return( -1 );
  110. }
  111. bInNano = ReadDwordSafe((ULONG) nt_cpu_info.in_nano_cpu);
  112. UMask = ReadDwordSafe((ULONG) nt_cpu_info.universe);
  113. lpContext->Eax = GetRegValue(nt_cpu_info.eax, bInNano, UMask);
  114. lpContext->Ecx = GetRegValue(nt_cpu_info.ecx, bInNano, UMask);
  115. lpContext->Edx = GetRegValue(nt_cpu_info.edx, bInNano, UMask);
  116. lpContext->Ebx = GetRegValue(nt_cpu_info.ebx, bInNano, UMask);
  117. lpContext->Ebp = GetRegValue(nt_cpu_info.ebp, bInNano, UMask);
  118. lpContext->Esi = GetRegValue(nt_cpu_info.esi, bInNano, UMask);
  119. lpContext->Edi = GetRegValue(nt_cpu_info.edi, bInNano, UMask);
  120. lpContext->Esp = GetEspValue(nt_cpu_info, bInNano);
  121. //
  122. // nt_cpu_info.flags isn't very much use, because several of the
  123. // flags values are not kept in memory, but computed each time.
  124. // The emulator doesn't supply us with the right value, so we
  125. // try to get it from the code in VdmDebugger
  126. //
  127. lpContext->EFlags = ReadDwordSafe(nt_cpu_info.flags);
  128. #if 0
  129. lpContext->EFlags = 0xffffffff; // indicate value unknown
  130. if (InVdmPrompt() &&
  131. (pTmp = (ULONG)EXPRESSION("ntvdmd!VdmDbgEFLAGS")) &&
  132. (READMEM((LPVOID) pTmp, &MyEflags, sizeof(DWORD)))) {
  133. lpContext->EFlags = MyEflags;
  134. }
  135. #endif
  136. lpContext->Eip = ReadDwordSafe(nt_cpu_info.eip);
  137. lpContext->SegEs = ReadWordSafe(nt_cpu_info.es);
  138. lpContext->SegCs = ReadWordSafe(nt_cpu_info.cs);
  139. lpContext->SegSs = ReadWordSafe(nt_cpu_info.ss);
  140. lpContext->SegDs = ReadWordSafe(nt_cpu_info.ds);
  141. lpContext->SegFs = ReadWordSafe(nt_cpu_info.fs);
  142. lpContext->SegGs = ReadWordSafe(nt_cpu_info.gs);
  143. } else {
  144. PRINTF("Could not find the symbol 'ntvdm!nt_cpu_info'\n");
  145. return( -1 );
  146. }
  147. if ( !(ReadDwordSafe(nt_cpu_info.cr0) & 1) ) {
  148. mode = V86_MODE;
  149. } else {
  150. mode = PROT_MODE;
  151. }
  152. return( mode );
  153. #else //
  154. NTSTATUS rc;
  155. BOOL b;
  156. int mode;
  157. ULONG lpVdmTib;
  158. ULONG IntelMSW;
  159. lpContext->ContextFlags = CONTEXT_FULL;
  160. rc = NtGetContextThread( hCurrentThread,
  161. lpContext );
  162. if ( NT_ERROR(rc) ) {
  163. PRINTF( "bde.k: Could not get current threads context - status = %08lX\n", rc );
  164. return( -1 );
  165. }
  166. /*
  167. ** Get the 16-bit registers from the context
  168. */
  169. if ( lpContext->EFlags & V86_BITS ) {
  170. /*
  171. ** V86 Mode
  172. */
  173. mode = V86_MODE;
  174. } else {
  175. if ( ((WORD)(lpContext->SegCs & RPL_MASK)) != KGDT_R3_CODE ) {
  176. mode = PROT_MODE;
  177. } else {
  178. /*
  179. ** We are in flat 32-bit address space!
  180. */
  181. lpVdmTib = GetCurrentVdmTib();
  182. if ( !lpVdmTib ) {
  183. PRINTF("Could not find the symbol 'VdmTib'\n");
  184. return( -1 );
  185. }
  186. b = READMEM((LPVOID)(lpVdmTib+FIELD_OFFSET(VDM_TIB,VdmContext)),
  187. lpContext, sizeof(VDMCONTEXT));
  188. if ( !b ) {
  189. PRINTF("Could not read IntelRegisters context out of process\n");
  190. return( -1 );
  191. }
  192. b = READMEM((LPVOID)(lpVdmTib+FIELD_OFFSET(VDM_TIB,IntelMSW)),
  193. &IntelMSW, sizeof(IntelMSW));
  194. if ( !b ) {
  195. PRINTF("Could not read IntelMSW out of process\n");
  196. return( -1 );
  197. }
  198. if ( IntelMSW & MSW_PE ) {
  199. mode = PROT_MODE;
  200. } else {
  201. mode = V86_MODE;
  202. }
  203. }
  204. }
  205. return( mode );
  206. #endif
  207. }
  208. ULONG
  209. GetIntelBase(
  210. VOID
  211. )
  212. {
  213. #ifndef i386
  214. ULONG IntelBase;
  215. BOOL b;
  216. IntelBase = (ULONG)EXPRESSION("ntvdm!Start_of_M_area");
  217. if ( IntelBase ) {
  218. b = READMEM((LPVOID) IntelBase, &IntelBase, sizeof(ULONG));
  219. if ( !b ) {
  220. PRINTF("Could not read symbol 'ntvdm!Start_of_M_area\n");
  221. return(0);
  222. }
  223. } else {
  224. PRINTF("Could not find the symbol 'ntvdm!Start_of_M_area'\n");
  225. }
  226. return(IntelBase);
  227. #else
  228. return(0);
  229. #endif
  230. }
  231. DWORD read_dword(
  232. ULONG lpAddress,
  233. BOOL bSafe
  234. ) {
  235. BOOL b;
  236. DWORD dword;
  237. b = READMEM((LPVOID)lpAddress, &dword, sizeof(dword));
  238. if ( !b ) {
  239. if ( !bSafe ) {
  240. PRINTF("Failure reading dword at memory location %08lX\n", lpAddress );
  241. }
  242. return( 0 );
  243. }
  244. return( dword );
  245. }
  246. WORD read_word(
  247. ULONG lpAddress,
  248. BOOL bSafe
  249. ) {
  250. BOOL b;
  251. WORD word;
  252. b = READMEM((LPVOID)lpAddress, &word, sizeof(word));
  253. if ( !b ) {
  254. if ( !bSafe ) {
  255. PRINTF("Failure reading word at memory location %08lX\n", lpAddress );
  256. }
  257. return( 0 );
  258. }
  259. return( word );
  260. }
  261. BYTE read_byte(
  262. ULONG lpAddress,
  263. BOOL bSafe
  264. ) {
  265. BOOL b;
  266. BYTE byte;
  267. b = READMEM((LPVOID)lpAddress, &byte, sizeof(byte));
  268. if ( !b ) {
  269. if ( !bSafe ) {
  270. PRINTF("Failure reading byte at memory location %08lX\n", lpAddress );
  271. }
  272. return( 0 );
  273. }
  274. return( byte );
  275. }
  276. BOOL read_gnode32(
  277. ULONG lpAddress,
  278. PGNODE32 p,
  279. BOOL bSafe
  280. ) {
  281. BOOL b;
  282. b = READMEM((LPVOID)lpAddress, p, sizeof(*p));
  283. if ( !b ) {
  284. if ( !bSafe ) {
  285. PRINTF("Failure reading word at memory location %08lX\n", lpAddress );
  286. }
  287. return( 0 );
  288. }
  289. return( TRUE );
  290. }
  291. BOOL GetDescriptorData(
  292. WORD selector,
  293. LPVDMLDT_ENTRY pdte
  294. )
  295. {
  296. //
  297. // Using GetThreadSelectorEntry would be nice if it just wasn't so slow.
  298. // So, we use our LDT, just like on risc, which should be good enough.
  299. //#ifdef i386
  300. #if 0
  301. LDT_ENTRY dte;
  302. if (!GetThreadSelectorEntry( hCurrentThread,
  303. selector,
  304. &dte)) {
  305. return( FALSE );
  306. }
  307. pdte->HighWord = dte.HighWord;
  308. pdte->BaseLow = dte.BaseLow;
  309. pdte->LimitLow = dte.LimitLow;
  310. return (TRUE);
  311. #endif
  312. NTSTATUS Status;
  313. selector &= ~(SELECTOR_LDT | SELECTOR_RPL);
  314. //
  315. // Get address of Ldt
  316. //
  317. if (!LdtAddress) {
  318. //
  319. // GetExpression is VERY SLOW under ntsd now. Who knows what the
  320. // debugger guys are up to. So just try to cache the address value
  321. // since it only changes twice (both during boot).
  322. //
  323. LdtAddress = (PVOID)EXPRESSION("ntvdm!Ldt");
  324. Status = READMEM(LdtAddress, &LdtAddress, sizeof(ULONG));
  325. if (!Status) {
  326. LdtAddress = NULL;
  327. return FALSE;
  328. }
  329. }
  330. Status = READMEM((PVOID)((ULONG)LdtAddress + selector),
  331. pdte, sizeof(VDMLDT_ENTRY));
  332. // Now do a special hack for the period of time during dpmi
  333. // init where the LDT moves. This would all be unecessary if
  334. // we just were to get the ldt base from VDMDBG, which knows
  335. // everything.
  336. if (((ULONG)LdtAddress)-GetIntelBase() < 0x100000) {
  337. LdtAddress = NULL; // forget the value again
  338. }
  339. return Status;
  340. }
  341. BOOL
  342. ReadMemExpression(
  343. LPSTR expr,
  344. LPVOID buffer,
  345. ULONG len
  346. )
  347. {
  348. PVOID pMem;
  349. pMem = (PVOID)(*GetExpression)(expr);
  350. if (!pMem) {
  351. PRINTF("Can't find symbol %s\n", expr);
  352. return FALSE;
  353. }
  354. if (!READMEM(pMem, buffer, len)) {
  355. PRINTF("Error reading memory\n");
  356. return FALSE;
  357. }
  358. return TRUE;
  359. }
  360. ULONG GetInfoFromSelector(
  361. WORD selector,
  362. int mode,
  363. SELECTORINFO *si
  364. ) {
  365. ULONG base;
  366. ULONG type;
  367. VDMLDT_ENTRY dte;
  368. switch( mode ) {
  369. case V86_MODE:
  370. base = (ULONG)selector << 4;
  371. if ( si ) {
  372. si->Limit = 0xFFFFL;
  373. si->Base = (ULONG)selector << 4;
  374. si->bCode = FALSE;
  375. si->bBig = FALSE;
  376. si->bExpandDown = FALSE;
  377. si->bWrite = TRUE;
  378. si->bPresent = TRUE;
  379. }
  380. break;
  381. case PROT_MODE:
  382. if ( !GetDescriptorData(selector, &dte) ) {
  383. return( (ULONG)-1 );
  384. }
  385. base = ((ULONG)dte.HighWord.Bytes.BaseHi << 24)
  386. + ((ULONG)dte.HighWord.Bytes.BaseMid << 16)
  387. + ((ULONG)dte.BaseLow);
  388. if ( si ) {
  389. si->Limit = (ULONG)dte.LimitLow
  390. + ((ULONG)dte.HighWord.Bits.LimitHi << 16);
  391. if ( dte.HighWord.Bits.Granularity ) {
  392. si->Limit <<= 12;
  393. si->Limit += 0xFFF;
  394. }
  395. si->Base = base;
  396. type = dte.HighWord.Bits.Type;
  397. si->bSystem = !(BOOL) (type & 0x10);
  398. if (!si->bSystem) {
  399. si->bCode = (BOOL) (type & 8);
  400. }
  401. si->bAccessed = (BOOL) (type & 1);
  402. si->bWrite = (BOOL) (type & 2);
  403. if (si->bCode) {
  404. si->bWrite = !si->bWrite;
  405. }
  406. si->bExpandDown = FALSE;
  407. if (!si->bSystem && !si->bCode) {
  408. si->bExpandDown = (BOOL) (type & 4);
  409. }
  410. si->bPresent = (BOOL) dte.HighWord.Bits.Pres;
  411. si->bBig = (BOOL) dte.HighWord.Bits.Default_Big;
  412. }
  413. break;
  414. case FLAT_MODE:
  415. PRINTF("Unsupported determination of base address in flat mode\n");
  416. base = 0;
  417. break;
  418. }
  419. return( base );
  420. }
  421. BOOL
  422. InVdmPrompt(
  423. VOID
  424. )
  425. {
  426. ULONG pTmp;
  427. BOOL InVdmDebugger;
  428. BOOL bReturn = FALSE;
  429. if ((pTmp = (ULONG)EXPRESSION("ntvdmd!InVdmDebugger")) &&
  430. (READMEM((LPVOID) pTmp, &InVdmDebugger, sizeof(BOOL)))) {
  431. bReturn = InVdmDebugger;
  432. }
  433. return bReturn;
  434. }
  435. //****************************************************************************
  436. //
  437. // Command line parsing routines
  438. //
  439. //****************************************************************************
  440. BOOL
  441. SkipToNextWhiteSpace(
  442. VOID
  443. )
  444. {
  445. char ch;
  446. while ( (ch = *lpArgumentString) != '\0' ) {
  447. if ( ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' ) {
  448. return TRUE;
  449. }
  450. lpArgumentString++;
  451. }
  452. return FALSE;
  453. }
  454. BOOL
  455. GetNextToken(
  456. VOID
  457. )
  458. {
  459. char ch;
  460. while ( (ch = *lpArgumentString) != '\0' ) {
  461. if ( ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n' ) {
  462. return TRUE;
  463. }
  464. lpArgumentString++;
  465. }
  466. return FALSE;
  467. }
  468. ULONG
  469. EvaluateToken(
  470. VOID
  471. )
  472. {
  473. char ch;
  474. LPSTR pTemp;
  475. ULONG value = 0;
  476. if (GetNextToken()) {
  477. pTemp = lpArgumentString;
  478. SkipToNextWhiteSpace();
  479. ch = *lpArgumentString;
  480. *lpArgumentString = 0;
  481. value = (ULONG) EXPRESSION( pTemp );
  482. *lpArgumentString = ch;
  483. }
  484. return (value);
  485. }
  486. BOOL
  487. IsTokenHex(
  488. VOID
  489. )
  490. {
  491. UCHAR ch;
  492. LPSTR pTemp;
  493. BOOL result = TRUE;
  494. if (GetNextToken()) {
  495. pTemp = lpArgumentString;
  496. SkipToNextWhiteSpace();
  497. lpArgumentString--;
  498. while(lpArgumentString >= pTemp) {
  499. ch = *lpArgumentString--;
  500. if (ch < '0') {
  501. result = FALSE;
  502. break;
  503. }
  504. if ((ch > '9') && (ch < 'A')) {
  505. result = FALSE;
  506. break;
  507. }
  508. if ((ch > 'F') && (ch < 'a')) {
  509. result = FALSE;
  510. break;
  511. }
  512. if (ch > 'f') {
  513. result = FALSE;
  514. break;
  515. }
  516. }
  517. lpArgumentString = pTemp;
  518. }
  519. return (result);
  520. }
  521. BOOL
  522. RegisterToAsciiValue(
  523. LPSTR *pszValue,
  524. LPSTR *pszReg
  525. )
  526. {
  527. LPSTR szReg = *pszReg;
  528. LPSTR szValue = *pszValue;
  529. if (!_strnicmp(szReg, "ax", 2) && !isalpha(szReg[2])) {
  530. _ultoa((ULONG)LOWORD(ThreadContext.Eax), szValue, 16);
  531. *pszReg += 2;
  532. } else if (!_strnicmp(szReg, "bx", 2) && !isalpha(szReg[2])) {
  533. _ultoa((ULONG)LOWORD(ThreadContext.Ebx), szValue, 16);
  534. *pszReg += 2;
  535. } else if (!_strnicmp(szReg, "cx", 2) && !isalpha(szReg[2])) {
  536. _ultoa((ULONG)LOWORD(ThreadContext.Ecx), szValue, 16);
  537. *pszReg += 2;
  538. } else if (!_strnicmp(szReg, "dx", 2) && !isalpha(szReg[2])) {
  539. _ultoa((ULONG)LOWORD(ThreadContext.Edx), szValue, 16);
  540. *pszReg += 2;
  541. } else if (!_strnicmp(szReg, "si", 2) && !isalpha(szReg[2])) {
  542. _ultoa((ULONG)LOWORD(ThreadContext.Esi), szValue, 16);
  543. *pszReg += 2;
  544. } else if (!_strnicmp(szReg, "di", 2) && !isalpha(szReg[2])) {
  545. _ultoa((ULONG)LOWORD(ThreadContext.Edi), szValue, 16);
  546. *pszReg += 2;
  547. } else if (!_strnicmp(szReg, "sp", 2) && !isalpha(szReg[2])) {
  548. _ultoa((ULONG)LOWORD(ThreadContext.Esp), szValue, 16);
  549. *pszReg += 2;
  550. } else if (!_strnicmp(szReg, "bp", 2) && !isalpha(szReg[2])) {
  551. _ultoa((ULONG)LOWORD(ThreadContext.Ebp), szValue, 16);
  552. *pszReg += 2;
  553. } else if (!_strnicmp(szReg, "ip", 2) && !isalpha(szReg[2])) {
  554. _ultoa((ULONG)LOWORD(ThreadContext.Eip), szValue, 16);
  555. *pszReg += 2;
  556. } else if (!_strnicmp(szReg, "eax", 3) && !isalpha(szReg[3])) {
  557. _ultoa(ThreadContext.Eax, szValue, 16);
  558. *pszReg += 3;
  559. } else if (!_strnicmp(szReg, "ebx", 3) && !isalpha(szReg[3])) {
  560. _ultoa(ThreadContext.Ebx, szValue, 16);
  561. *pszReg += 3;
  562. } else if (!_strnicmp(szReg, "ecx", 3) && !isalpha(szReg[3])) {
  563. _ultoa(ThreadContext.Ecx, szValue, 16);
  564. *pszReg += 3;
  565. } else if (!_strnicmp(szReg, "edx", 3) && !isalpha(szReg[3])) {
  566. _ultoa(ThreadContext.Edx, szValue, 16);
  567. *pszReg += 3;
  568. } else if (!_strnicmp(szReg, "esi", 3) && !isalpha(szReg[3])) {
  569. _ultoa(ThreadContext.Esi, szValue, 16);
  570. *pszReg += 3;
  571. } else if (!_strnicmp(szReg, "edi", 3) && !isalpha(szReg[3])) {
  572. _ultoa(ThreadContext.Edi, szValue, 16);
  573. *pszReg += 3;
  574. } else if (!_strnicmp(szReg, "esp", 3) && !isalpha(szReg[3])) {
  575. _ultoa(ThreadContext.Esp, szValue, 16);
  576. *pszReg += 3;
  577. } else if (!_strnicmp(szReg, "ebp", 3) && !isalpha(szReg[3])) {
  578. _ultoa(ThreadContext.Ebp, szValue, 16);
  579. *pszReg += 3;
  580. } else if (!_strnicmp(szReg, "eip", 3) && !isalpha(szReg[3])) {
  581. _ultoa(ThreadContext.Eip, szValue, 16);
  582. *pszReg += 3;
  583. } else if (!_strnicmp(szReg, "cs", 2) && !isalpha(szReg[2])) {
  584. _ultoa((ULONG)ThreadContext.SegCs, szValue, 16);
  585. *pszReg += 2;
  586. } else if (!_strnicmp(szReg, "ds", 2) && !isalpha(szReg[2])) {
  587. _ultoa((ULONG)ThreadContext.SegDs, szValue, 16);
  588. *pszReg += 2;
  589. } else if (!_strnicmp(szReg, "es", 2) && !isalpha(szReg[2])) {
  590. _ultoa((ULONG)ThreadContext.SegEs, szValue, 16);
  591. *pszReg += 2;
  592. } else if (!_strnicmp(szReg, "fs", 2) && !isalpha(szReg[2])) {
  593. _ultoa((ULONG)ThreadContext.SegFs, szValue, 16);
  594. *pszReg += 2;
  595. } else if (!_strnicmp(szReg, "gs", 2) && !isalpha(szReg[2])) {
  596. _ultoa((ULONG)ThreadContext.SegGs, szValue, 16);
  597. *pszReg += 2;
  598. } else if (!_strnicmp(szReg, "ss", 2) && !isalpha(szReg[2])) {
  599. _ultoa((ULONG)ThreadContext.SegSs, szValue, 16);
  600. *pszReg += 2;
  601. } else {
  602. return FALSE;
  603. }
  604. // PRINTF("value = %s\n", szValue);
  605. while (*szValue) {
  606. szValue++;
  607. }
  608. *pszValue = szValue;
  609. return TRUE;
  610. }
  611. VOID
  612. ParseForIntelRegisters(
  613. LPSTR szTarg,
  614. LPSTR szSrc
  615. )
  616. {
  617. while (*szSrc) {
  618. if (!isalpha(*szSrc)) {
  619. if (!isdigit(*szSrc)) {
  620. *szTarg++ = *szSrc++;
  621. continue;
  622. }
  623. while (isalpha(*szSrc) || isdigit(*szSrc)) {
  624. *szTarg++ = *szSrc++;
  625. }
  626. continue;
  627. }
  628. if (!RegisterToAsciiValue(&szTarg, &szSrc)) {
  629. while (isalpha(*szSrc) || isdigit(*szSrc)) {
  630. *szTarg++ = *szSrc++;
  631. }
  632. }
  633. }
  634. *szTarg = 0;
  635. }
  636. BOOL
  637. ParseIntelAddress(
  638. int *pMode,
  639. WORD *pSelector,
  640. PULONG pOffset
  641. )
  642. {
  643. char sel_text[128], off_text[128];
  644. char expr_text[256];
  645. char *colon;
  646. char *mode_prefix;
  647. WORD segment;
  648. char filename[9];
  649. colon = strchr( lpArgumentString, ':' );
  650. if ( colon == NULL ) {
  651. LPSTR pSymbol = lpArgumentString;
  652. BOOL bResult;
  653. char chTemp;
  654. SkipToNextWhiteSpace();
  655. chTemp = *lpArgumentString;
  656. *lpArgumentString = 0;
  657. bResult = FindAddress( pSymbol,
  658. filename,
  659. &segment,
  660. pSelector,
  661. pOffset,
  662. pMode,
  663. FALSE);
  664. *lpArgumentString = chTemp;
  665. if (bResult) {
  666. if (*pMode == NOT_LOADED) {
  667. PRINTF("Could not determine base of '%s'\n", pSymbol);
  668. return FALSE;
  669. } else {
  670. return TRUE;
  671. }
  672. } else {
  673. PRINTF("Could not find symbol: %s\n", pSymbol);
  674. return FALSE;
  675. }
  676. }
  677. *pMode = GetContext( &ThreadContext );
  678. mode_prefix = strchr( lpArgumentString, '&' );
  679. if ( mode_prefix == NULL ) {
  680. mode_prefix = strchr( lpArgumentString, '#' );
  681. if ( mode_prefix != NULL ) {
  682. if ( mode_prefix != lpArgumentString ) {
  683. PRINTF("Address must have '&' symbol as the first character\n");
  684. return FALSE;
  685. }
  686. *pMode = PROT_MODE;
  687. lpArgumentString = mode_prefix+1;
  688. }
  689. } else {
  690. if ( mode_prefix != lpArgumentString ) {
  691. PRINTF("Address must have '#' symbol as the first character\n");
  692. return FALSE;
  693. }
  694. *pMode = V86_MODE;
  695. lpArgumentString = mode_prefix+1;
  696. }
  697. *colon = '\0';
  698. strcpy( sel_text, lpArgumentString );
  699. *colon = ':';
  700. strcpy( off_text, colon+1 );
  701. ParseForIntelRegisters(expr_text, sel_text);
  702. *pSelector = (WORD) EXPRESSION( expr_text );
  703. ParseForIntelRegisters(expr_text, off_text);
  704. *pOffset = (ULONG) EXPRESSION( expr_text );
  705. SkipToNextWhiteSpace();
  706. return TRUE;
  707. }