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.

720 lines
18 KiB

  1. /* demmisc.c - Misc. SVC routines
  2. *
  3. * demLoadDos
  4. *
  5. * Modification History:
  6. *
  7. * Sudeepb 31-Mar-1991 Created
  8. */
  9. #include "dem.h"
  10. #include "demmsg.h"
  11. // #include "demdasd.h"
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <softpc.h>
  15. #include <mvdm.h>
  16. #include <dbgsvc.h>
  17. #include <nt_vdd.h>
  18. #include <host_def.h>
  19. #if DEVL
  20. // int 21h func names
  21. // index off of function number in ah
  22. char *scname[] = {
  23. "Terminate Program",
  24. "Read Kbd with Echo",
  25. "Display Character",
  26. "Auxillary Input",
  27. "Auxillary Output",
  28. "Print Character",
  29. "Direct Con Output",
  30. "Direct Con Input",
  31. "Read Kbd without Echo",
  32. "Display String",
  33. "Read String",
  34. "Check Keyboard Status",
  35. "Flush Buffer,Read Kbd",
  36. "Reset Drive",
  37. "Set Default Drive",
  38. "FCB Open",
  39. "FCB Close",
  40. "FCB Find First",
  41. "FCB Find Next",
  42. "FCB Delete",
  43. "FCB Seq Read",
  44. "FCB Seq Write",
  45. "FCB Create",
  46. "FCB Rename",
  47. "18h??",
  48. "Get Default Drive",
  49. "Set Disk Transfer Addr",
  50. "Get Default Drive Data",
  51. "Get Drive Data",
  52. "1Dh??",
  53. "1Eh??",
  54. "Get Default DPB",
  55. "20h??",
  56. "FCB Random Read",
  57. "FCB Random Write",
  58. "FCB Get File Size",
  59. "FCB Set Random Record",
  60. "Set Interrupt Vector",
  61. "Create Process Data Block",
  62. "FCB Random Read Block",
  63. "FCB Random Write Block",
  64. "FCB Parse File Name",
  65. "Get Date",
  66. "Set Date",
  67. "Get Time",
  68. "Set Time",
  69. "SetReset Write Verify",
  70. "Get Disk Transefr Addr",
  71. "Get Version Number",
  72. "Keep Process",
  73. "Get Drive Parameters",
  74. "GetSet CTRL C",
  75. "Get InDOS Flag",
  76. "Get Interrupt Vector",
  77. "Get Disk Free Space",
  78. "Char Oper",
  79. "GetSet Country/Region Info",
  80. "Make Dir",
  81. "Remove Dir",
  82. "Change DirDir",
  83. "Create File",
  84. "Open File",
  85. "Close File",
  86. "Read File",
  87. "Write File",
  88. "Delete File",
  89. "Move File Ptr",
  90. "GetSet File Attr",
  91. "IOCTL",
  92. "Dup File Handle",
  93. "Force Dup Handle",
  94. "Get Current Dir",
  95. "Alloc Mem",
  96. "Free Mem",
  97. "Realloc Mem",
  98. "Exec Process",
  99. "Exit Process",
  100. "Get Child Process Exit Code",
  101. "Find First",
  102. "Find Next",
  103. "Set Current PSP",
  104. "Get Current PSP",
  105. "Get In Vars",
  106. "Set DPB",
  107. "Get Verify On Write",
  108. "Dup PDB",
  109. "Rename File",
  110. "GetSet File Date and Time",
  111. "Allocation Strategy",
  112. "Get Extended Error",
  113. "Create Temp File",
  114. "Create New File",
  115. "LockUnlock File",
  116. "SetExtendedErrorNetwork-ServerCall",
  117. "Network-UserOper",
  118. "Network-AssignOper",
  119. "xNameTrans",
  120. "PathParse",
  121. "GetCurrentPSP",
  122. "ECS CALL",
  123. "Set Printer Flag",
  124. "Extended Country Info",
  125. "GetSet CodePage",
  126. "Set Max Handle",
  127. "Commit File",
  128. "GetSetMediaID",
  129. "6ah??",
  130. "IFS IOCTL",
  131. "Extended OpenCreate",
  132. "6d??",
  133. "6e??",
  134. "6f??",
  135. "70??",
  136. "LFN API"
  137. };
  138. #endif
  139. extern BOOL IsFirstCall;
  140. extern void nt_floppy_release_lock(void);
  141. LPSTR pszBIOSDirectory;
  142. LPSTR pszDOSDirectory;
  143. // internal func prototype
  144. BOOL IsDebuggee(void);
  145. void SignalSegmentNotice(WORD wType,
  146. WORD wModuleSeg,
  147. WORD wLoadSeg,
  148. WORD wNewSeg,
  149. LPSTR lpName,
  150. DWORD dwImageLen );
  151. /* demLoadDos - Load NTDOS.SYS.
  152. *
  153. * This SVC is made by NTIO.SYS to load NTDOS.SYS.
  154. *
  155. * Entry - Client (DI) - Load Segment
  156. *
  157. * Exit - SUCCESS returns
  158. * FAILURE Kills the VDM
  159. */
  160. VOID demLoadDos (VOID)
  161. {
  162. PBYTE pbLoadAddr;
  163. HANDLE hfile;
  164. DWORD BytesRead;
  165. #ifdef FE_SB
  166. LANGID LcId = GetSystemDefaultLangID();
  167. #endif //FE_SB
  168. // get linear address where ntdos.sys will be loaded
  169. pbLoadAddr = (PBYTE) GetVDMAddr(getDI(),0);
  170. // set up BIOS path string
  171. if(DbgIsDebuggee() &&
  172. ((pszBIOSDirectory = (PCHAR)malloc (ulSystem32PathLen +
  173. 1 + sizeof(NTIO_409) + sizeof(NTIO_411) + 1 )) != NULL)) {
  174. memcpy (pszBIOSDirectory, pszSystem32Path, ulSystem32PathLen);
  175. #ifdef FE_SB
  176. switch (LcId) {
  177. case MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT):
  178. memcpy (pszBIOSDirectory + ulSystem32PathLen, NTIO_411, strlen(NTIO_411)+1);
  179. break;
  180. case MAKELANGID(LANG_KOREAN,SUBLANG_DEFAULT):
  181. memcpy (pszBIOSDirectory + ulSystem32PathLen, NTIO_412, strlen(NTIO_412)+1);
  182. break;
  183. case MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL):
  184. memcpy (pszBIOSDirectory + ulSystem32PathLen, NTIO_404, strlen(NTIO_404)+1);
  185. break;
  186. case MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED):
  187. case MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_HONGKONG):
  188. memcpy (pszBIOSDirectory + ulSystem32PathLen, NTIO_804, strlen(NTIO_804)+1);
  189. break;
  190. default:
  191. memcpy (pszBIOSDirectory + ulSystem32PathLen, NTIO_409, strlen(NTIO_409)+1);
  192. break;
  193. }
  194. #else
  195. strcat (pszBIOSDirectory,"\\ntio.sys");
  196. #endif
  197. }
  198. // prepare the dos file name
  199. if ((pszDOSDirectory = (PCHAR)malloc (ulSystem32PathLen + 1 + 8 + 1 + 3 + 1 + 1)) == NULL) {
  200. RcErrorDialogBox(EG_MALLOC_FAILURE,NULL,NULL);
  201. TerminateVDM ();
  202. }
  203. memcpy (pszDOSDirectory, pszSystem32Path, ulSystem32PathLen);
  204. #ifdef FE_SB
  205. switch (LcId)
  206. {
  207. case MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT):
  208. memcpy (pszDOSDirectory + ulSystem32PathLen, NTDOS_411, strlen(NTDOS_411)+1);
  209. break;
  210. case MAKELANGID(LANG_KOREAN,SUBLANG_DEFAULT):
  211. memcpy (pszDOSDirectory + ulSystem32PathLen, NTDOS_412, strlen(NTDOS_412)+1);
  212. break;
  213. case MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL):
  214. memcpy (pszDOSDirectory + ulSystem32PathLen, NTDOS_404, strlen(NTDOS_404)+1);
  215. break;
  216. case MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED):
  217. case MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_HONGKONG):
  218. memcpy (pszDOSDirectory + ulSystem32PathLen, NTDOS_804, strlen(NTDOS_804)+1);
  219. break;
  220. default:
  221. memcpy (pszDOSDirectory + ulSystem32PathLen, NTDOS_409, strlen(NTDOS_409)+1);
  222. break;
  223. }
  224. #else
  225. memcpy (pszDOSDirectory + ulSystem32PathLen, NTDOS_409, strlen(NTDOS_409)+1);
  226. #endif
  227. hfile = CreateFileOem(pszDOSDirectory,
  228. GENERIC_READ,
  229. FILE_SHARE_READ,
  230. NULL,
  231. OPEN_EXISTING,
  232. FILE_ATTRIBUTE_NORMAL,
  233. NULL );
  234. if (hfile == (HANDLE)0xffffffff) {
  235. TerminateVDM();
  236. }
  237. BytesRead = 1;
  238. while (BytesRead) {
  239. if (!ReadFile(hfile, pbLoadAddr, 16384, &BytesRead, NULL)) {
  240. TerminateVDM();
  241. }
  242. pbLoadAddr = (PBYTE)((ULONG)pbLoadAddr + BytesRead);
  243. }
  244. CloseHandle (hfile);
  245. if (!DbgIsDebuggee()) {
  246. free(pszDOSDirectory);
  247. }
  248. return;
  249. }
  250. /* demDOSDispCall
  251. *
  252. * This SVC is made by System_Call upon entering the dos
  253. *
  254. *
  255. * Entry: Client registers as per user app upon entry to dos
  256. *
  257. * Exit - SUCCESS returns, if being debugged and DEMDOSDISP&fShowSvcMsg
  258. * dumps user app's registers and service name
  259. */
  260. VOID demDOSDispCall(VOID)
  261. {
  262. #if DEVL
  263. WORD ax;
  264. if (!DbgIsDebuggee()) {
  265. return;
  266. }
  267. if (fShowSVCMsg & DEMDOSDISP) {
  268. ax = getAX();
  269. sprintf(demDebugBuffer,"demDosDispCall %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n",
  270. scname[HIBYTE(ax)],
  271. ax,getBX(),getCX(),getDX(),getDI(), getSI());
  272. OutputDebugStringOem(demDebugBuffer);
  273. sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x\n",
  274. getCS(),getIP(), getDS(),getES(),getSS(),getSP()+2,getBP());
  275. OutputDebugStringOem(demDebugBuffer);
  276. }
  277. #endif
  278. }
  279. /* demDOSDispRet
  280. *
  281. * This SVC is made by System_Call upon exiting from the dos
  282. *
  283. * Entry: Client registers as per user app upon exit to dos
  284. *
  285. * Exit - SUCCESS returns, if being debugged and DEMDOSDISP&fShowSvcMsg
  286. * dumps user app's registers
  287. */
  288. VOID demDOSDispRet(VOID)
  289. {
  290. #if DEVL
  291. PWORD16 pStk;
  292. if (!DbgIsDebuggee()) {
  293. return;
  294. }
  295. if (fShowSVCMsg & DEMDOSDISP) {
  296. // get ptr to flag word on stack
  297. pStk = (WORD *)GetVDMAddr(getSS(), getSP());
  298. pStk += 2;
  299. sprintf (demDebugBuffer,"demDosDispRet\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n",
  300. getAX(),getBX(),getCX(),getDX(),getDI(),getSI());
  301. OutputDebugStringOem(demDebugBuffer);
  302. sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x CF=%.1x\n",
  303. getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP(), (*pStk) & 1);
  304. OutputDebugStringOem(demDebugBuffer);
  305. }
  306. #endif
  307. }
  308. /* demEntryDosApp - Dump Entry Point Dos Apps
  309. *
  310. * This SVC is made by NTDOS.SYS,$exec just prior to entering dos app
  311. *
  312. * Entry - Client DS:SI points to entry point
  313. * Client AX:DI points to initial stack
  314. * Client DX has PDB pointer
  315. *
  316. * Exit - SUCCESS returns, if being debugged and DEMDOSAPPBREAK&fShowSvcMsg
  317. * breaks to debugger
  318. */
  319. VOID demEntryDosApp(VOID)
  320. {
  321. USHORT PDB;
  322. PDB = getDX();
  323. if(!IsFirstCall)
  324. VDDCreateUserHook(PDB);
  325. if (!DbgIsDebuggee()) {
  326. return;
  327. }
  328. DbgDosAppStart(getDS(), getSI());
  329. #if DEVL
  330. if (fShowSVCMsg & DEMDOSAPPBREAK) {
  331. sprintf(demDebugBuffer,"demEntryDosApp: Entry=%.4x:%.4x, Stk=%.4x:%.4x PDB=%.4x\n",
  332. getCS(),getIP(),getAX(),getDI(),PDB);
  333. OutputDebugStringOem(demDebugBuffer);
  334. DebugBreak();
  335. }
  336. #endif
  337. }
  338. /* demLoadDosAppSym - Load Dos Apps Symbols
  339. *
  340. * This SVC is made by NTDOS.SYS,$exec to load Dos App symbols
  341. *
  342. * Entry - Client ES:DI -Fully Qualified Path Name of executable
  343. * Client BX -Load Segment\Reloc Factor
  344. * Client DX:AX -HIWORD:LOWORD exe size
  345. *
  346. * Exit - SUCCESS returns, raises debug exception, if being debugged
  347. *
  348. */
  349. VOID demLoadDosAppSym(VOID)
  350. {
  351. SignalSegmentNotice(DBG_MODLOAD,
  352. 0, getBX(), 0,
  353. (LPSTR)GetVDMAddr(getES(),getDI()),
  354. MAKELONG(getAX(), getDX()) );
  355. }
  356. /* demFreeDosAppSym - Free Dos Apps Symbols
  357. *
  358. * This SVC is made by NTDOS.SYS,$exec to Free Dos App symbols
  359. *
  360. * Entry - Client ES:DI -Fully Qualified Path Name of executable
  361. *
  362. * Exit - SUCCESS returns, raises debug exception, if being debugged
  363. *
  364. */
  365. VOID demFreeDosAppSym(VOID)
  366. {
  367. SignalSegmentNotice(DBG_MODFREE,
  368. 0, 0, 0,
  369. (LPSTR)GetVDMAddr(getES(), getDI()),
  370. 0);
  371. }
  372. /* demSystemSymbolOp - Manipulate Symbols for special modules
  373. *
  374. * This SVC is made by NTDOS.SYS,NTIO.SYS
  375. *
  376. * Client AH -Operation
  377. * Client AL -module identifier
  378. * Client BX -Load Segment\Reloc Factor
  379. * Client CX:DX -HIWORD:LOWORD exe size
  380. *
  381. * Exit - SUCCESS returns, raises debug exception, if being debugged
  382. *
  383. */
  384. VOID demSystemSymbolOp(VOID)
  385. {
  386. LPSTR pszPathName;
  387. if (!DbgIsDebuggee()) {
  388. return;
  389. }
  390. switch(getAL()) {
  391. case ID_NTIO:
  392. pszPathName = pszBIOSDirectory;
  393. break;
  394. case ID_NTDOS:
  395. pszPathName = pszDOSDirectory;
  396. break;
  397. default:
  398. pszPathName = NULL;
  399. }
  400. // check this again for the case where the static strings have been freed
  401. if (pszPathName != NULL) {
  402. switch(getAH() & (255-SYMOP_CLEANUP)) {
  403. case SYMOP_LOAD:
  404. SignalSegmentNotice(DBG_MODLOAD,
  405. 0, getBX(), 0,
  406. pszPathName,
  407. MAKELONG(getDX(), getCX()) );
  408. break;
  409. case SYMOP_FREE:
  410. //bugbug not implemented yet
  411. break;
  412. case SYMOP_MOVE:
  413. SignalSegmentNotice(DBG_SEGMOVE,
  414. getDI(), getBX(), getES(),
  415. pszPathName,
  416. MAKELONG(getDX(), getCX()) );
  417. break;
  418. }
  419. }
  420. if (getAH() & SYMOP_CLEANUP) {
  421. if (pszBIOSDirectory != NULL) {
  422. free (pszBIOSDirectory);
  423. }
  424. if (pszDOSDirectory != NULL) {
  425. free(pszDOSDirectory);
  426. }
  427. }
  428. }
  429. VOID demOutputString(VOID)
  430. {
  431. LPSTR lpText;
  432. UCHAR fPE;
  433. if ( !DbgIsDebuggee() ) {
  434. return;
  435. }
  436. fPE = ISPESET;
  437. lpText = (LPSTR)Sim32GetVDMPointer(
  438. ((ULONG)getDS() << 16) + (ULONG)getSI(),
  439. (ULONG)getBX(), fPE );
  440. OutputDebugStringOem( lpText );
  441. }
  442. VOID demInputString(VOID)
  443. {
  444. LPSTR lpText;
  445. UCHAR fPE;
  446. if ( !DbgIsDebuggee() ) {
  447. return;
  448. }
  449. fPE = ISPESET;
  450. lpText = (LPSTR)Sim32GetVDMPointer(
  451. ((ULONG)getDS() << 16) + (ULONG)getDI(),
  452. (ULONG)getBX(), fPE );
  453. DbgPrompt( "", lpText, 0x80 );
  454. }
  455. /* SignalSegmentNotice
  456. *
  457. * packs up the data and raises STATUS_SEGMENT_NOTIFICATION
  458. *
  459. * Entry - WORD wType - DBG_MODLOAD, DBG_MODFREE
  460. * WORD wModuleSeg- segment number within module (1 based)
  461. * WORD wLoadSeg - Starting Segment (reloc factor)
  462. * LPSTR lpName - ptr to Name of Image
  463. * DWORD dwModLen - Length of module
  464. *
  465. *
  466. * if wType ==DBG_MODLOAD wOldLoadSeg is unused
  467. * if wType ==DBG_MODFREE wLoadSeg,dwImageLen,wOldLoadSeg are unused
  468. *
  469. * Use 0 or NULL for unused parameters
  470. *
  471. * Exit - void
  472. *
  473. */
  474. void SignalSegmentNotice(WORD wType,
  475. WORD wModuleSeg,
  476. WORD wLoadSeg,
  477. WORD wNewSeg,
  478. LPSTR lpName,
  479. DWORD dwImageLen )
  480. {
  481. int i;
  482. DWORD dw;
  483. LPSTR lpstr;
  484. LPSTR lpModuleName;
  485. char ach[MAX_PATH+9]; // 9 for module name
  486. if (!DbgIsDebuggee()) {
  487. return;
  488. }
  489. // create file name
  490. dw = GetFullPathNameOemSys(lpName,
  491. sizeof(ach)-9, // 9 for module name
  492. ach,
  493. &lpstr,
  494. TRUE);
  495. if (!dw || dw >= sizeof(ach)) {
  496. lpName = " ";
  497. strcpy(ach, lpName);
  498. }
  499. else {
  500. lpName = lpstr;
  501. }
  502. // copy in module name
  503. i = 8; // limit len of module name
  504. lpModuleName = lpstr = ach+strlen(ach)+1;
  505. while (*lpName && *lpName != '.' && i--)
  506. {
  507. *lpstr++ = *lpName++;
  508. }
  509. *lpstr = '\0';
  510. #if DBG
  511. if (fShowSVCMsg) {
  512. sprintf(demDebugBuffer,"dem Segment Notify: <%s> Seg=%lxh, ImageLen=%ld\n",
  513. ach, (DWORD)wLoadSeg, dwImageLen);
  514. OutputDebugStringOem(demDebugBuffer);
  515. }
  516. #endif
  517. // Send it to the debugger
  518. DbgSegmentNotice(wType, wModuleSeg, wLoadSeg, wNewSeg, lpModuleName, ach, dwImageLen);
  519. }
  520. /* demIsDebug - Determine if 16bit DOS should make entry/exit calls at int21
  521. *
  522. * Entry: void
  523. *
  524. * Exit: Client AL = 0 if not
  525. * Client AL = 1 if yes
  526. *
  527. */
  528. VOID demIsDebug(void)
  529. {
  530. BYTE dbgflags = 0;
  531. if (DbgIsDebuggee()) {
  532. dbgflags |= ISDBG_DEBUGGEE;
  533. if (fShowSVCMsg)
  534. dbgflags |= ISDBG_SHOWSVC;
  535. }
  536. setAL (dbgflags);
  537. return;
  538. }
  539. /* demDiskReset - Reset floppy disks.
  540. *
  541. * Entry - None
  542. *
  543. * Exit - FDAccess in DOSDATA (NTDOS.SYS) is 0.
  544. */
  545. VOID demDiskReset (VOID)
  546. {
  547. extern WORD * pFDAccess; // defined in SoftPC.
  548. HostFloppyReset();
  549. HostFdiskReset();
  550. *pFDAccess = 0;
  551. return;
  552. }
  553. /* demExitVDM - Kill the VDM From 16Bit side with a proper message
  554. * in case something goes wrong.
  555. *
  556. * Entry - None
  557. *
  558. * Exit - None (VDM Is killed)
  559. */
  560. VOID demExitVDM ( VOID )
  561. {
  562. RcErrorDialogBox(ED_BADSYSFILE,"config.nt",NULL);
  563. TerminateVDM ();
  564. }
  565. /* demWOWFiles - Return what should be the value of files= for WOW VDM.
  566. *
  567. * Entry - AL - files= specified in config.sys
  568. *
  569. * Exit - client AL is set to max if WOW VDM else unmodified
  570. */
  571. VOID demWOWFiles ( VOID )
  572. {
  573. if(VDMForWOW)
  574. setAL (255);
  575. return;
  576. }
  577. /** GetDOSAppName - Return the name of the current DOS executable
  578. *
  579. * ENTRY -
  580. * OUT ppszApp Name: address of the app
  581. *
  582. * EXIT
  583. * SUCCESS - Returns SUCCESS
  584. * FAILURE - Returns FAILURE
  585. *
  586. * Comments:
  587. * This routine uses the current PDB to figure out the name of the currently
  588. * executing DOS application.
  589. */
  590. VOID GetDOSAppName(LPSTR pszAppName)
  591. {
  592. PCHAR pch = NULL;
  593. PUSHORT pusEnvSeg;
  594. #define PDB_ENV_OFFSET 0x2c
  595. if (pusCurrentPDB) {
  596. pusEnvSeg = (PUSHORT)Sim32GetVDMPointer((*pusCurrentPDB) << 16, 0, 0);
  597. pusEnvSeg = (PUSHORT)((PCHAR)pusEnvSeg + PDB_ENV_OFFSET);
  598. // Get a pointer to the environment
  599. if (VDMForWOW || (getMSW() & MSW_PE)) {
  600. pch = (PCHAR)Sim32GetVDMPointer(*pusEnvSeg << 16, 1, TRUE);
  601. } else {
  602. pch = (PCHAR)Sim32GetVDMPointer(*pusEnvSeg << 16, 0, 0);
  603. }
  604. }
  605. if (NULL == pch) {
  606. *pszAppName = '\0';
  607. }
  608. else {
  609. // Walk through the environment strings until we get to the command line
  610. while (*pch) {
  611. pch += strlen(pch) + 1;
  612. }
  613. pch += 3; // skip past the double null and string count
  614. strcpy(pszAppName, pch);
  615. }
  616. }