- Start implementing a user menu for mounting/unmounting floppy disks at runtime. Menu state refresh & proper localization remain to be done.
- Add a temporary "Sleep(INFINITE)" where the VdmShutdown function is susceptible to trigger again a VDM cleanup in case it was called again in parallel. For diagnosing CORE-10182, see also r69366.

svn path=/trunk/; revision=69375
This commit is contained in:
Hermès Bélusca-Maïto 2015-09-27 15:24:26 +00:00
parent 7d4f528f60
commit fbb3c519c3
19 changed files with 354 additions and 80 deletions

View file

@ -73,5 +73,5 @@ list(APPEND SOURCE
add_executable(ntvdm ${SOURCE}) add_executable(ntvdm ${SOURCE})
set_module_type(ntvdm win32cui UNICODE IMAGEBASE 0x0F000000) set_module_type(ntvdm win32cui UNICODE IMAGEBASE 0x0F000000)
target_link_libraries(ntvdm fast486 ${PSEH_LIB}) target_link_libraries(ntvdm fast486 ${PSEH_LIB})
add_importlibs(ntvdm user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_importlibs(ntvdm user32 gdi32 advapi32 comdlg32 msvcrt kernel32 ntdll)
add_cd_file(TARGET ntvdm DESTINATION reactos/system32 FOR all) add_cd_file(TARGET ntvdm DESTINATION reactos/system32 FOR all)

View file

@ -686,9 +686,9 @@ BOOLEAN DiskBios32Initialize(VOID)
/* Detect and initialize the supported disks */ /* Detect and initialize the supported disks */
// TODO: the "Detect" part is missing. // TODO: the "Detect" part is missing.
FloppyDrive[0] = &XDCFloppyDrive[0]; FloppyDrive[0] = RetrieveDisk(FLOPPY_DISK, 0);
FloppyDrive[1] = &XDCFloppyDrive[1]; FloppyDrive[1] = RetrieveDisk(FLOPPY_DISK, 1);
HardDrive[0] = &XDCHardDrive[0]; HardDrive[0] = RetrieveDisk(HARD_DISK, 0);
return TRUE; return TRUE;
} }

View file

@ -405,6 +405,51 @@ VOID DumpMemory(BOOLEAN TextFormat)
DPRINT1("Memory dump done\n"); DPRINT1("Memory dump done\n");
} }
VOID MountFloppy(IN ULONG DiskNumber)
{
// FIXME: This should be present in PSDK commdlg.h
//
// FlagsEx Values
#if (_WIN32_WINNT >= 0x0500)
#define OFN_EX_NOPLACESBAR 0x00000001
#endif // (_WIN32_WINNT >= 0x0500)
OPENFILENAMEA ofn;
CHAR szFile[MAX_PATH] = "";
RtlZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hConsoleWnd;
ofn.lpstrTitle = "Select a virtual floppy image";
ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// ofn.FlagsEx = OFN_EX_NOPLACESBAR;
ofn.lpstrFilter = "Virtual floppy images (*.vfd;*.img;*.ima;*.dsk)\0*.vfd\0All files (*.*)\0*.*\0";
ofn.lpstrDefExt = "vfd";
ofn.nFilterIndex = 0;
ofn.lpstrFile = szFile;
ofn.nMaxFile = ARRAYSIZE(szFile);
if (!GetOpenFileNameA(&ofn))
{
DPRINT1("CommDlgExtendedError = %d\n", CommDlgExtendedError());
return;
}
// TODO: Refresh the menu state
if (!MountDisk(FLOPPY_DISK, DiskNumber, szFile, !!(ofn.Flags & OFN_READONLY)))
DisplayMessage(L"An error happened when mounting disk %d", DiskNumber);
}
VOID EjectFloppy(IN ULONG DiskNumber)
{
// TODO: Refresh the menu state
if (!UnmountDisk(FLOPPY_DISK, DiskNumber))
DisplayMessage(L"An error happened when ejecting disk %d", DiskNumber);
}
VOID EmulatorPause(VOID) VOID EmulatorPause(VOID)
{ {
/* Pause the VDM */ /* Pause the VDM */
@ -506,6 +551,18 @@ BOOLEAN EmulatorInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
return FALSE; return FALSE;
} }
#if 0
// The following commands are examples of MountDisk usage.
// NOTE: Those values are hardcoded paths on my local test machines!!
// MountDisk(FLOPPY_DISK, 0, "H:\\trunk\\ntvdm_studies\\diskette_high.vfd", TRUE);
// MountDisk(FLOPPY_DISK, 0, "H:\\DOS_tests\\Dos5.0.img", TRUE);
// MountDisk(FLOPPY_DISK, 0, "H:\\trunk\\ntvdm_studies\\hdd_10Mo_fixed.vhd", TRUE);
// MountDisk(FLOPPY_DISK, 0, "H:\\DOS_tests\\diskette_test.vfd", FALSE);
MountDisk(HARD_DISK, 0, "H:\\DOS_tests\\MS-DOS 6_fixed_size.vhd", FALSE);
#endif
/* Initialize the software callback system and register the emulator BOPs */ /* Initialize the software callback system and register the emulator BOPs */
InitializeInt32(); InitializeInt32();
RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop); RegisterBop(BOP_DEBUGGER , EmulatorDebugBreakBop);

View file

@ -98,6 +98,9 @@ extern BOOLEAN VdmRunning;
VOID DumpMemory(BOOLEAN TextFormat); VOID DumpMemory(BOOLEAN TextFormat);
VOID MountFloppy(IN ULONG DiskNumber);
VOID EjectFloppy(IN ULONG DiskNumber);
UCHAR FASTCALL EmulatorIntAcknowledge UCHAR FASTCALL EmulatorIntAcknowledge
( (
PFAST486_STATE State PFAST486_STATE State

View file

@ -156,8 +156,7 @@ calculate_geometry(ULONG64 total_sectors, PUSHORT cyls,
/*************************** FLOPPY DISK CONTROLLER ***************************/ /*************************** FLOPPY DISK CONTROLLER ***************************/
// A Floppy Controller can support up to 4 floppy drives. // A Floppy Controller can support up to 4 floppy drives.
/*static*/ static DISK_IMAGE XDCFloppyDrive[4];
DISK_IMAGE XDCFloppyDrive[4];
// Taken from DOSBox // Taken from DOSBox
typedef struct _DISK_GEO typedef struct _DISK_GEO
@ -239,8 +238,7 @@ MountFDI(IN PDISK_IMAGE DiskImage,
// An IDE Hard Disk Controller can support up to 4 drives: // An IDE Hard Disk Controller can support up to 4 drives:
// Primary Master Drive, Primary Slave Drive, // Primary Master Drive, Primary Slave Drive,
// Secondary Master Drive, Secondary Slave Drive. // Secondary Master Drive, Secondary Slave Drive.
/*static*/ static DISK_IMAGE XDCHardDrive[4];
DISK_IMAGE XDCHardDrive[4];
BOOLEAN BOOLEAN
MountHDD(IN PDISK_IMAGE DiskImage, MountHDD(IN PDISK_IMAGE DiskImage,
@ -468,21 +466,59 @@ WriteDisk(IN PDISK_IMAGE DiskImage,
typedef BOOLEAN (*MOUNT_DISK_HANDLER)(IN PDISK_IMAGE DiskImage, IN HANDLE hFile); typedef BOOLEAN (*MOUNT_DISK_HANDLER)(IN PDISK_IMAGE DiskImage, IN HANDLE hFile);
typedef struct _DISK_MOUNT_INFO
{
PDISK_IMAGE DiskArray;
ULONG NumDisks;
MOUNT_DISK_HANDLER MountDiskHelper;
} DISK_MOUNT_INFO, *PDISK_MOUNT_INFO;
static DISK_MOUNT_INFO DiskMountInfo[MAX_DISK_TYPE] =
{
{XDCFloppyDrive, ARRAYSIZE(XDCFloppyDrive), MountFDI},
{XDCHardDrive , ARRAYSIZE(XDCHardDrive) , MountHDD},
};
PDISK_IMAGE
RetrieveDisk(IN DISK_TYPE DiskType,
IN ULONG DiskNumber)
{
ASSERT(DiskType < MAX_DISK_TYPE);
if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
{
DisplayMessage(L"RetrieveDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
return NULL;
}
return &DiskMountInfo[DiskType].DiskArray[DiskNumber];
}
BOOLEAN BOOLEAN
MountDisk(IN PDISK_IMAGE DiskImage, MountDisk(IN DISK_TYPE DiskType,
MOUNT_DISK_HANDLER MountDiskHelper, IN ULONG DiskNumber,
IN PCSTR FileName, IN PCSTR FileName,
IN BOOLEAN ReadOnly) IN BOOLEAN ReadOnly)
{ {
BOOLEAN Success = FALSE; BOOLEAN Success = FALSE;
PDISK_IMAGE DiskImage;
HANDLE hFile; HANDLE hFile;
BY_HANDLE_FILE_INFORMATION FileInformation; BY_HANDLE_FILE_INFORMATION FileInformation;
ASSERT(DiskType < MAX_DISK_TYPE);
if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
{
DisplayMessage(L"MountDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
return FALSE;
}
DiskImage = &DiskMountInfo[DiskType].DiskArray[DiskNumber];
if (IsDiskPresent(DiskImage)) if (IsDiskPresent(DiskImage))
{ {
DisplayMessage(L"MountDisk: Disk 0x%p already in use.", DiskImage); DPRINT1("MountDisk: Disk %d:%d:0x%p already in use, recycling...\n", DiskType, DiskNumber, DiskImage);
return FALSE; UnmountDisk(DiskType, DiskNumber);
} }
/* Try to open the file */ /* Try to open the file */
@ -540,7 +576,7 @@ MountDisk(IN PDISK_IMAGE DiskImage,
} }
/* Success, mount the image */ /* Success, mount the image */
if (!MountDiskHelper(DiskImage, hFile)) if (!DiskMountInfo[DiskType].MountDiskHelper(DiskImage, hFile))
{ {
DisplayMessage(L"MountDisk: Failed to mount disk file '%S' in 0x%p.", FileName, DiskImage); DisplayMessage(L"MountDisk: Failed to mount disk file '%S' in 0x%p.", FileName, DiskImage);
goto Quit; goto Quit;
@ -553,11 +589,23 @@ Quit:
} }
BOOLEAN BOOLEAN
UnmountDisk(IN PDISK_IMAGE DiskImage) UnmountDisk(IN DISK_TYPE DiskType,
IN ULONG DiskNumber)
{ {
PDISK_IMAGE DiskImage;
ASSERT(DiskType < MAX_DISK_TYPE);
if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
{
DisplayMessage(L"UnmountDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
return FALSE;
}
DiskImage = &DiskMountInfo[DiskType].DiskArray[DiskNumber];
if (!IsDiskPresent(DiskImage)) if (!IsDiskPresent(DiskImage))
{ {
DisplayMessage(L"UnmountDisk: Disk 0x%p is already unmounted.", DiskImage); DPRINT1("UnmountDisk: Disk %d:%d:0x%p is already unmounted\n", DiskType, DiskNumber, DiskImage);
return FALSE; return FALSE;
} }
@ -573,28 +621,20 @@ UnmountDisk(IN PDISK_IMAGE DiskImage)
BOOLEAN DiskCtrlInitialize(VOID) BOOLEAN DiskCtrlInitialize(VOID)
{ {
#if 0
// The following commands are examples of MountDisk usage.
// NOTE: Those values are hardcoded paths on my local test machines!!
// MountDisk(&XDCFloppyDrive[0], MountFDI, "H:\\trunk\\ntvdm_studies\\diskette_high.vfd", TRUE);
// MountDisk(&XDCFloppyDrive[0], MountFDI, "H:\\DOS_tests\\Dos5.0.img", TRUE);
// MountDisk(&XDCHardDrive[0] , MountHDD, "H:\\trunk\\ntvdm_studies\\hdd_10Mo_fixed.vhd", TRUE);
MountDisk(&XDCFloppyDrive[0], MountFDI, "H:\\DOS_tests\\diskette_test.vfd", FALSE);
MountDisk(&XDCHardDrive[0] , MountHDD, "H:\\DOS_tests\\MS-DOS 6_fixed_size.vhd", FALSE);
#endif
return TRUE; return TRUE;
} }
VOID DiskCtrlCleanup(VOID) VOID DiskCtrlCleanup(VOID)
{ {
#if 0 ULONG DiskNumber;
// The following commands are examples of UnmountDisk usage.
UnmountDisk(&XDCHardDrive[0]); /* Unmount all the floppy disk drives */
UnmountDisk(&XDCFloppyDrive[0]); for (DiskNumber = 0; DiskNumber < DiskMountInfo[FLOPPY_DISK].NumDisks; ++DiskNumber)
#endif UnmountDisk(FLOPPY_DISK, DiskNumber);
/* Unmount all the hard disk drives */
for (DiskNumber = 0; DiskNumber < DiskMountInfo[HARD_DISK].NumDisks; ++DiskNumber)
UnmountDisk(HARD_DISK, DiskNumber);
} }
/* EOF */ /* EOF */

View file

@ -39,9 +39,12 @@ typedef struct _DISK_IMAGE
} DISK_IMAGE, *PDISK_IMAGE; } DISK_IMAGE, *PDISK_IMAGE;
// HACKHACK! For dskbios32.c typedef enum _DISK_TYPE
extern DISK_IMAGE XDCFloppyDrive[]; {
extern DISK_IMAGE XDCHardDrive[]; FLOPPY_DISK,
HARD_DISK,
MAX_DISK_TYPE
} DISK_TYPE;
/* FUNCTIONS ******************************************************************/ /* FUNCTIONS ******************************************************************/
@ -68,6 +71,20 @@ WriteDisk(IN PDISK_IMAGE DiskImage,
IN BYTE Sector, IN BYTE Sector,
IN BYTE NumSectors); IN BYTE NumSectors);
PDISK_IMAGE
RetrieveDisk(IN DISK_TYPE DiskType,
IN ULONG DiskNumber);
BOOLEAN
MountDisk(IN DISK_TYPE DiskType,
IN ULONG DiskNumber,
IN PCSTR FileName,
IN BOOLEAN ReadOnly);
BOOLEAN
UnmountDisk(IN DISK_TYPE DiskType,
IN ULONG DiskNumber);
BOOLEAN DiskCtrlInitialize(VOID); BOOLEAN DiskCtrlInitialize(VOID);
VOID DiskCtrlCleanup(VOID); VOID DiskCtrlCleanup(VOID);

View file

@ -17,5 +17,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)" IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)"
IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)" IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&Ukončit ReactOS VDM" IDS_VDM_QUIT , "&Ukončit ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)" IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)"
IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)" IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "ReactOS VDM b&eenden" IDS_VDM_QUIT , "ReactOS VDM b&eenden"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)" IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)"
IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)" IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&Quit the ReactOS VDM" IDS_VDM_QUIT , "&Quit the ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)" IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)"
IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)" IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&Salir de ReactOS VDM" IDS_VDM_QUIT , "&Salir de ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Vidage Mémoire (&Texte)" IDS_VDM_DUMPMEM_TXT , "Vidage Mémoire (&Texte)"
IDS_VDM_DUMPMEM_BIN , "Vidage Mémoire (&Binaire)" IDS_VDM_DUMPMEM_BIN , "Vidage Mémoire (&Binaire)"
IDS_VDM_MOUNT_FLOPPY, "Insérer une disquette dans le lecteur %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Éjecter la disquette du lecteur %d"
IDS_VDM_QUIT , "&Quitter la ReactOS VDM" IDS_VDM_QUIT , "&Quitter la ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)" IDS_VDM_DUMPMEM_TXT , "Dump Memory (&Text)"
IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)" IDS_VDM_DUMPMEM_BIN , "Dump Memory (&Binary)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&Esci da ReactOS VDM" IDS_VDM_QUIT , "&Esci da ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -13,5 +13,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Zrzut pamięci (&Tekst)" IDS_VDM_DUMPMEM_TXT , "Zrzut pamięci (&Tekst)"
IDS_VDM_DUMPMEM_BIN , "Zrzut pamięci (&Binarny)" IDS_VDM_DUMPMEM_BIN , "Zrzut pamięci (&Binarny)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&Wyjdź z ReactOS VDM" IDS_VDM_QUIT , "&Wyjdź z ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Captură memorie (te&xt)" IDS_VDM_DUMPMEM_TXT , "Captură memorie (te&xt)"
IDS_VDM_DUMPMEM_BIN , "Captură memorie (&binară)" IDS_VDM_DUMPMEM_BIN , "Captură memorie (&binară)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "I&eșire din ReactOS VDM" IDS_VDM_QUIT , "I&eșire din ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -11,5 +11,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "Дамп памяти (&Текстовый)" IDS_VDM_DUMPMEM_TXT , "Дамп памяти (&Текстовый)"
IDS_VDM_DUMPMEM_BIN , "Дамп памяти (&Бинарный)" IDS_VDM_DUMPMEM_BIN , "Дамп памяти (&Бинарный)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&Выйти из ReactOS VDM" IDS_VDM_QUIT , "&Выйти из ReactOS VDM"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -13,5 +13,12 @@ STRINGTABLE
BEGIN BEGIN
IDS_VDM_DUMPMEM_TXT , "&Bellek Dökümünü Al (Metin)" IDS_VDM_DUMPMEM_TXT , "&Bellek Dökümünü Al (Metin)"
IDS_VDM_DUMPMEM_BIN , "B&ellek Dökümünü Al (İkili)" IDS_VDM_DUMPMEM_BIN , "B&ellek Dökümünü Al (İkili)"
IDS_VDM_MOUNT_FLOPPY, "Insert a floppy in drive %d <%s>..."
IDS_VDM_EJECT_FLOPPY, "Eject floppy from drive %d"
IDS_VDM_QUIT , "&ReactOS VDM'den Çık" IDS_VDM_QUIT , "&ReactOS VDM'den Çık"
END END
STRINGTABLE
BEGIN
IDS_NO_MEDIA, "No media"
END

View file

@ -30,7 +30,7 @@ static DWORD OrgConsoleInputMode, OrgConsoleOutputMode;
INT NtVdmArgc; INT NtVdmArgc;
WCHAR** NtVdmArgv; WCHAR** NtVdmArgv;
HWND hConsoleWnd = NULL;
static HMENU hConsoleMenu = NULL; static HMENU hConsoleMenu = NULL;
static INT VdmMenuPos = -1; static INT VdmMenuPos = -1;
static BOOLEAN ShowPointer = FALSE; static BOOLEAN ShowPointer = FALSE;
@ -42,13 +42,17 @@ typedef struct _VDM_MENUITEM
{ {
UINT uID; UINT uID;
const struct _VDM_MENUITEM *SubMenu; const struct _VDM_MENUITEM *SubMenu;
WORD wCmdID; UINT_PTR uCmdID;
} VDM_MENUITEM, *PVDM_MENUITEM; } VDM_MENUITEM, *PVDM_MENUITEM;
static const VDM_MENUITEM VdmMenuItems[] = static const VDM_MENUITEM VdmMenuItems[] =
{ {
{ IDS_VDM_DUMPMEM_TXT, NULL, ID_VDM_DUMPMEM_TXT }, { IDS_VDM_DUMPMEM_TXT, NULL, ID_VDM_DUMPMEM_TXT },
{ IDS_VDM_DUMPMEM_BIN, NULL, ID_VDM_DUMPMEM_BIN }, { IDS_VDM_DUMPMEM_BIN, NULL, ID_VDM_DUMPMEM_BIN },
{ -1, NULL, 0 }, /* Separator */
// { IDS_VDM_MOUNT_FLOPPY, NULL, ID_VDM_DRIVES },
// { IDS_VDM_EJECT_FLOPPY, NULL, ID_VDM_DRIVES },
{ -1, NULL, 0 }, /* Separator */
{ IDS_VDM_QUIT , NULL, ID_VDM_QUIT }, { IDS_VDM_QUIT , NULL, ID_VDM_QUIT },
{ 0, NULL, 0 } /* End of list */ { 0, NULL, 0 } /* End of list */
@ -57,7 +61,7 @@ static const VDM_MENUITEM VdmMenuItems[] =
static const VDM_MENUITEM VdmMainMenuItems[] = static const VDM_MENUITEM VdmMainMenuItems[] =
{ {
{ -1, NULL, 0 }, /* Separator */ { -1, NULL, 0 }, /* Separator */
{ IDS_HIDE_MOUSE, NULL, ID_SHOWHIDE_MOUSE }, /* Hide mouse; can be renamed to Show mouse */ { IDS_HIDE_MOUSE, NULL, ID_SHOWHIDE_MOUSE }, /* "Hide mouse"; can be renamed to "Show mouse" */
{ IDS_VDM_MENU , VdmMenuItems, 0 }, /* ReactOS VDM Menu */ { IDS_VDM_MENU , VdmMenuItems, 0 }, /* ReactOS VDM Menu */
{ 0, NULL, 0 } /* End of list */ { 0, NULL, 0 } /* End of list */
@ -68,7 +72,7 @@ AppendMenuItems(HMENU hMenu,
const VDM_MENUITEM *Items) const VDM_MENUITEM *Items)
{ {
UINT i = 0; UINT i = 0;
WCHAR szMenuString[255]; WCHAR szMenuString[256];
HMENU hSubMenu; HMENU hSubMenu;
do do
@ -100,7 +104,7 @@ AppendMenuItems(HMENU hMenu,
{ {
AppendMenuW(hMenu, AppendMenuW(hMenu,
MF_STRING, MF_STRING,
Items[i].wCmdID, Items[i].uCmdID,
szMenuString); szMenuString);
} }
} }
@ -113,7 +117,7 @@ AppendMenuItems(HMENU hMenu,
NULL); NULL);
} }
i++; i++;
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].uCmdID == 0));
} }
BOOL BOOL
@ -138,9 +142,15 @@ VdmMenuExists(HMENU hConsoleMenu)
/*static*/ VOID /*static*/ VOID
CreateVdmMenu(HANDLE ConOutHandle) CreateVdmMenu(HANDLE ConOutHandle)
{ {
HMENU hVdmSubMenu;
UINT_PTR ItemID = ID_VDM_DRIVES;
UINT Pos;
WCHAR szNoMedia[100];
WCHAR szMenuString1[256], szMenuString2[256];
hConsoleMenu = ConsoleMenuControl(ConOutHandle, hConsoleMenu = ConsoleMenuControl(ConOutHandle,
ID_SHOWHIDE_MOUSE, ID_SHOWHIDE_MOUSE,
ID_VDM_QUIT); ID_VDM_DRIVES + 4);
if (hConsoleMenu == NULL) return; if (hConsoleMenu == NULL) return;
/* Get the position where we are going to insert our menu items */ /* Get the position where we are going to insert our menu items */
@ -149,8 +159,52 @@ CreateVdmMenu(HANDLE ConOutHandle)
/* Really add the menu if it doesn't already exist (in case eg. NTVDM crashed) */ /* Really add the menu if it doesn't already exist (in case eg. NTVDM crashed) */
if (!VdmMenuExists(hConsoleMenu)) if (!VdmMenuExists(hConsoleMenu))
{ {
/* Add all the menu entries */
AppendMenuItems(hConsoleMenu, VdmMainMenuItems); AppendMenuItems(hConsoleMenu, VdmMainMenuItems);
DrawMenuBar(GetConsoleWindow());
/* Add the removable drives menu entries */
hVdmSubMenu = GetSubMenu(hConsoleMenu, VdmMenuPos + 2); // VdmMenuItems
Pos = 3; // After the 2 items and the separator in VdmMenuItems
LoadStringW(GetModuleHandle(NULL),
IDS_NO_MEDIA,
szNoMedia,
ARRAYSIZE(szNoMedia));
LoadStringW(GetModuleHandle(NULL),
IDS_VDM_MOUNT_FLOPPY,
szMenuString1,
ARRAYSIZE(szMenuString1));
/* Drive 0 -- Mount */
_snwprintf(szMenuString2, ARRAYSIZE(szMenuString2), szMenuString1, 0, szNoMedia);
szMenuString2[ARRAYSIZE(szMenuString2) - 1] = UNICODE_NULL;
InsertMenuW(hVdmSubMenu, Pos++, MF_STRING | MF_BYPOSITION, ItemID + 0, szMenuString2);
/* Drive 1 -- Mount */
_snwprintf(szMenuString2, ARRAYSIZE(szMenuString2), szMenuString1, 1, szNoMedia);
szMenuString2[ARRAYSIZE(szMenuString2) - 1] = UNICODE_NULL;
InsertMenuW(hVdmSubMenu, Pos++, MF_STRING | MF_BYPOSITION, ItemID + 2, szMenuString2);
LoadStringW(GetModuleHandle(NULL),
IDS_VDM_EJECT_FLOPPY,
szMenuString1,
ARRAYSIZE(szMenuString1));
/* Drive 0 -- Eject */
_snwprintf(szMenuString2, ARRAYSIZE(szMenuString2), szMenuString1, 0);
szMenuString2[ARRAYSIZE(szMenuString2) - 1] = UNICODE_NULL;
InsertMenuW(hVdmSubMenu, Pos++, MF_STRING | MF_BYPOSITION, ItemID + 1, szMenuString2);
/* Drive 1 -- Eject */
_snwprintf(szMenuString2, ARRAYSIZE(szMenuString2), szMenuString1, 1);
szMenuString2[ARRAYSIZE(szMenuString2) - 1] = UNICODE_NULL;
InsertMenuW(hVdmSubMenu, Pos++, MF_STRING | MF_BYPOSITION, ItemID + 3, szMenuString2);
// TODO: Refresh the menu state
/* Refresh the menu */
DrawMenuBar(hConsoleWnd);
} }
} }
@ -164,14 +218,14 @@ DestroyVdmMenu(VOID)
{ {
DeleteMenu(hConsoleMenu, VdmMenuPos, MF_BYPOSITION); DeleteMenu(hConsoleMenu, VdmMenuPos, MF_BYPOSITION);
i++; i++;
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); } while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].uCmdID == 0));
DrawMenuBar(GetConsoleWindow()); DrawMenuBar(hConsoleWnd);
} }
static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr) static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
{ {
WCHAR szMenuString[255] = L""; WCHAR szMenuString[256];
if (ShowPtr) if (ShowPtr)
{ {
@ -267,7 +321,7 @@ DisplayMessage(IN LPCWSTR Format, ...)
/* Display the message */ /* Display the message */
DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer); DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer);
MessageBoxW(NULL, Buffer, L"NTVDM Subsystem", MB_OK); MessageBoxW(hConsoleWnd, Buffer, L"NTVDM Subsystem", MB_OK);
#ifndef WIN2K_COMPLIANT #ifndef WIN2K_COMPLIANT
/* Free the buffer if needed */ /* Free the buffer if needed */
@ -291,6 +345,7 @@ VdmShutdown(BOOLEAN Immediate)
if (MustShutdown) if (MustShutdown)
{ {
DPRINT1("Shutdown is ongoing...\n"); DPRINT1("Shutdown is ongoing...\n");
Sleep(INFINITE);
return; return;
} }
@ -343,6 +398,7 @@ ConsoleCtrlHandler(DWORD ControlType)
static VOID static VOID
ConsoleInitUI(VOID) ConsoleInitUI(VOID)
{ {
hConsoleWnd = GetConsoleWindow();
CreateVdmMenu(ConsoleOutput); CreateVdmMenu(ConsoleOutput);
} }
@ -469,6 +525,26 @@ VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent)
DumpMemory(FALSE); DumpMemory(FALSE);
break; break;
/* Drive 0 -- Mount */
/* Drive 1 -- Mount */
case ID_VDM_DRIVES + 0:
case ID_VDM_DRIVES + 2:
{
ULONG DiskNumber = (MenuEvent->dwCommandId - ID_VDM_DRIVES) / 2;
MountFloppy(DiskNumber);
break;
}
/* Drive 0 -- Eject */
/* Drive 1 -- Eject */
case ID_VDM_DRIVES + 1:
case ID_VDM_DRIVES + 3:
{
ULONG DiskNumber = (MenuEvent->dwCommandId - ID_VDM_DRIVES - 1) / 2;
EjectFloppy(DiskNumber);
break;
}
case ID_VDM_QUIT: case ID_VDM_QUIT:
/* Stop the VDM */ /* Stop the VDM */
// EmulatorTerminate(); // EmulatorTerminate();

View file

@ -24,6 +24,8 @@
#include <winnls.h> #include <winnls.h>
#include <winreg.h> #include <winreg.h>
#include <winuser.h> #include <winuser.h>
#include <commdlg.h>
#include <subsys/win/vdm.h> #include <subsys/win/vdm.h>
// Do not include stuff that is only defined // Do not include stuff that is only defined
@ -73,6 +75,8 @@ DWORD WINAPI SetLastConsoleEventActive(VOID);
extern INT NtVdmArgc; extern INT NtVdmArgc;
extern WCHAR** NtVdmArgv; extern WCHAR** NtVdmArgv;
extern HWND hConsoleWnd;
/* /*
* Interface functions * Interface functions

View file

@ -6,6 +6,9 @@
#define ID_VDM_DUMPMEM_BIN 1002 #define ID_VDM_DUMPMEM_BIN 1002
#define ID_VDM_QUIT 1003 #define ID_VDM_QUIT 1003
/* Menu IDs for removable media */
#define ID_VDM_DRIVES 1010
/* String IDs */ /* String IDs */
#define IDS_HIDE_MOUSE 100 #define IDS_HIDE_MOUSE 100
#define IDS_SHOW_MOUSE 101 #define IDS_SHOW_MOUSE 101
@ -13,7 +16,11 @@
#define IDS_VDM_DUMPMEM_TXT 200 #define IDS_VDM_DUMPMEM_TXT 200
#define IDS_VDM_DUMPMEM_BIN 201 #define IDS_VDM_DUMPMEM_BIN 201
#define IDS_VDM_QUIT 202 #define IDS_VDM_MOUNT_FLOPPY 202
#define IDS_VDM_EJECT_FLOPPY 203
#define IDS_VDM_QUIT 204
#define IDS_NO_MEDIA 300
/* Icon */ /* Icon */
#define IDI_APPICON 1 #define IDI_APPICON 1