www.digitalmars.com         C & C++   DMDScript  

c++.dos.32-bits - get machine name

reply peter <peter_member pathlink.com> writes:
Hi

I'm having problem with the following code compiled under DOSX. I've been stuck
on this for a couple of days but seem to get nowhere. 

Any help would be much appreciated.

I'm using the orginal Symantec compiler control version 7.2b2.
Library: sdx.lib 25/06/1998 10:53

I want to get the computer name of the workstation running my DOSX program so I
decided to use an interrupt call 0x5e00, however the machine name is never
returned. 

Code:


#include <dos.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>

void main()
{

char  buffer[17] = "<buffer-------->";

union  REGS  regs_in, regs_out;

regs_in.e.eax = 0x5e00;
regs_in.e.ebx = 0;
regs_in.e.ecx = 0;
regs_in.e.edx = (unsigned)buffer;
regs_in.e.cflag = 0;

regs_out.e.eax = 0;
regs_out.e.ebx = 0;
regs_out.e.ecx = 0;
regs_out.e.edx = 0;
regs_out.e.cflag = 0;

printf("\n REGS IN ax:%x bx:%x cx:%x dx:%x cflag:%x",
regs_in.e.eax,
regs_in.e.ebx,
regs_in.e.ecx,
regs_in.e.edx,
regs_in.e.cflag
);
printf("\n REGS OUT ax:%x bx:%x cx:%x dx:%x cflag:%x",
regs_out.e.eax,
regs_out.e.ebx,
regs_out.e.ecx,
regs_out.e.edx,
regs_out.e.cflag
);


printf("\nbuffer = {%s}", buffer);

int86(0x21, &regs_in, &regs_out);

printf("\nbuffer = {%s}", buffer);

printf("\n REGS IN ax:%x bx:%x cx:%x dx:%x cflag:%x",
regs_in.e.eax,
regs_in.e.ebx,
regs_in.e.ecx,
regs_in.e.edx,
regs_in.e.cflag
);

printf("\n REGS OUT ax:%x bx:%x cx:%x dx:%x cflag:%x",
regs_out.e.eax,
regs_out.e.ebx,
regs_out.e.ecx,
regs_out.e.edx,
regs_out.e.cflag
);

}

Thanks for any help

Regards
Peter
Feb 01 2005
parent reply Heinz Saathoff <hsaat despammed.com> writes:
Hello Peter,

peter wrote...
 I'm having problem with the following code compiled under DOSX. I've been stuck
 on this for a couple of days but seem to get nowhere. 
 
 Any help would be much appreciated.
 
 I'm using the orginal Symantec compiler control version 7.2b2.
 Library: sdx.lib 25/06/1998 10:53
 
 I want to get the computer name of the workstation running my DOSX program so I
 decided to use an interrupt call 0x5e00, however the machine name is never
 returned. 
 
 [Code snipped]

The DOSX extender doesn't support several DOS calls directly. These can be called indirectly only. For additional information (such as this machine name) a buffer is needed that can be accessed in both real and protected mode. It's a bit tricky to do. I've rewritten the code to work here. It works when compiled with the actual DigitalMars Compiler and DOSX from http://www.dosextender.com I don't know if it also runs with the DOS extender that was supplied with Symantec 7.2. If not you may try to upgrade. BTW, when loading the actual DOS-extender you will also find a manual with viewer where all the supported functions are documented. Regards, Heinz =================== CODE ================== #include <dos.h> #include <stdio.h> #pragma pack(push,2) struct RMI { // struct to call real mode interrupts unsigned short irq_num; unsigned short ds; unsigned short es; unsigned short fs; unsigned short gs; unsigned long eax; unsigned long edx; }; #pragma pack(pop) struct XR_BUFFER { char __far *pp; // x32 protected mode pointer; unsigned short segm; // real mode segment unsigned short offs; // real mode offset }; struct XR_BUFFER GetBufferAdr() { struct XR_BUFFER xr; asm { push es mov eax,0x250d // Get Transfer Buffer Address int 0x21 mov xr.offs,bx shr ebx,16 mov xr.segm,bx mov bx,es // seg mov DWord Ptr xr.pp,edx mov Word Ptr xr.pp+4,bx pop es } return xr; } int main() { struct XR_BUFFER x32_dos_buffer; struct RMI rmi; char local_buffer[64]; int i; x32_dos_buffer = GetBufferAdr(); fprintf(stderr, "Real(%04x:%04x), Prot(%04x:%08x)\n", x32_dos_buffer.segm, x32_dos_buffer.offs, FP_SEG(x32_dos_buffer.pp), FP_OFF(x32_dos_buffer)); rmi.irq_num = 0x21; // DOS interrupt rmi.eax = 0x5e00; // get machine name rmi.edx = x32_dos_buffer.offs; /* real mode offset of transfer buffer */ rmi.ds = x32_dos_buffer.segm; // real mode offset asm { mov eax,0x2511 lea edx,rmi int 0x21 } // now information is in transfer buffer // because the extender uses this buffer when doing I/O we copy // the contents to a local buffer first; for(i=0; i<64 && (local_buffer[i]=x32_dos_buffer.pp[i])!=0; ++i) ; printf("Name returned is %s\n", local_buffer); return 0; }//main ================== end CODE ===============
Feb 03 2005
parent reply Peter <Peter_member pathlink.com> writes:
Hi Heinz,

Thanks for your post.

I tried your code on Symantec 7.2 compiler with its dos extender but did not
work.

I will do as you have suggested and will look at upgrading the dos extender
first to see if it will work with the Symantec compiler, if it still fails I
will use DM.

Kind regards

Peter

In article <MPG.1c6c40156eb8758d9896ee news.digitalmars.com>, Heinz Saathoff
says...
Hello Peter,

peter wrote...
 I'm having problem with the following code compiled under DOSX. I've been stuck
 on this for a couple of days but seem to get nowhere. 
 
 Any help would be much appreciated.
 
 I'm using the orginal Symantec compiler control version 7.2b2.
 Library: sdx.lib 25/06/1998 10:53
 
 I want to get the computer name of the workstation running my DOSX program so I
 decided to use an interrupt call 0x5e00, however the machine name is never
 returned. 
 
 [Code snipped]

The DOSX extender doesn't support several DOS calls directly. These can be called indirectly only. For additional information (such as this machine name) a buffer is needed that can be accessed in both real and protected mode. It's a bit tricky to do. I've rewritten the code to work here. It works when compiled with the actual DigitalMars Compiler and DOSX from http://www.dosextender.com I don't know if it also runs with the DOS extender that was supplied with Symantec 7.2. If not you may try to upgrade. BTW, when loading the actual DOS-extender you will also find a manual with viewer where all the supported functions are documented. Regards, Heinz =================== CODE ================== #include <dos.h> #include <stdio.h> #pragma pack(push,2) struct RMI { // struct to call real mode interrupts unsigned short irq_num; unsigned short ds; unsigned short es; unsigned short fs; unsigned short gs; unsigned long eax; unsigned long edx; }; #pragma pack(pop) struct XR_BUFFER { char __far *pp; // x32 protected mode pointer; unsigned short segm; // real mode segment unsigned short offs; // real mode offset }; struct XR_BUFFER GetBufferAdr() { struct XR_BUFFER xr; asm { push es mov eax,0x250d // Get Transfer Buffer Address int 0x21 mov xr.offs,bx shr ebx,16 mov xr.segm,bx mov bx,es // seg mov DWord Ptr xr.pp,edx mov Word Ptr xr.pp+4,bx pop es } return xr; } int main() { struct XR_BUFFER x32_dos_buffer; struct RMI rmi; char local_buffer[64]; int i; x32_dos_buffer = GetBufferAdr(); fprintf(stderr, "Real(%04x:%04x), Prot(%04x:%08x)\n", x32_dos_buffer.segm, x32_dos_buffer.offs, FP_SEG(x32_dos_buffer.pp), FP_OFF(x32_dos_buffer)); rmi.irq_num = 0x21; // DOS interrupt rmi.eax = 0x5e00; // get machine name rmi.edx = x32_dos_buffer.offs; /* real mode offset of transfer buffer */ rmi.ds = x32_dos_buffer.segm; // real mode offset asm { mov eax,0x2511 lea edx,rmi int 0x21 } // now information is in transfer buffer // because the extender uses this buffer when doing I/O we copy // the contents to a local buffer first; for(i=0; i<64 && (local_buffer[i]=x32_dos_buffer.pp[i])!=0; ++i) ; printf("Name returned is %s\n", local_buffer); return 0; }//main ================== end CODE ===============

Feb 07 2005
parent Peter <Peter_member pathlink.com> writes:
Hi Heinz,

Thanks for the snippet of code. Orignally I couldn't get this code to work on
the symantec compiler 7.2 with its built in dos extender.

The code GPF on line

   for(i=0; i<64 && (local_buffer[i]=x32_dos_buffer.pp[i])!=0; ++i) ;


For some reason it didn't like the pointer x32_dos_buffer.pp Therefore I created a pointer from the real mode segment/offset, and this worked, but I don't understand why it didn't like the protected mode ptr. This worked. char *ptr = (char *) (-_x386_get_abs_address(MK_FP(getDS(), 0)) + (x32_dos_buffer.segm << 4) + x32_dos_buffer.offs); for(i=0; i<64 && (local_buffer[i]=*ptr)!=0; ptr++, ++i) ; I compiled the program using "sc -mx compname.cpp" Anyway, thanks for your help Heinz. In article <cu7nqg$1uhi$1 digitaldaemon.com>, Peter says...
Hi Heinz,

Thanks for your post.

I tried your code on Symantec 7.2 compiler with its dos extender but did not
work.

I will do as you have suggested and will look at upgrading the dos extender
first to see if it will work with the Symantec compiler, if it still fails I
will use DM.

Kind regards

Peter

In article <MPG.1c6c40156eb8758d9896ee news.digitalmars.com>, Heinz Saathoff
says...
Hello Peter,

peter wrote...
 I'm having problem with the following code compiled under DOSX. I've been stuck
 on this for a couple of days but seem to get nowhere. 
 
 Any help would be much appreciated.
 
 I'm using the orginal Symantec compiler control version 7.2b2.
 Library: sdx.lib 25/06/1998 10:53
 
 I want to get the computer name of the workstation running my DOSX program so I
 decided to use an interrupt call 0x5e00, however the machine name is never
 returned. 
 
 [Code snipped]

The DOSX extender doesn't support several DOS calls directly. These can be called indirectly only. For additional information (such as this machine name) a buffer is needed that can be accessed in both real and protected mode. It's a bit tricky to do. I've rewritten the code to work here. It works when compiled with the actual DigitalMars Compiler and DOSX from http://www.dosextender.com I don't know if it also runs with the DOS extender that was supplied with Symantec 7.2. If not you may try to upgrade. BTW, when loading the actual DOS-extender you will also find a manual with viewer where all the supported functions are documented. Regards, Heinz =================== CODE ================== #include <dos.h> #include <stdio.h> #pragma pack(push,2) struct RMI { // struct to call real mode interrupts unsigned short irq_num; unsigned short ds; unsigned short es; unsigned short fs; unsigned short gs; unsigned long eax; unsigned long edx; }; #pragma pack(pop) struct XR_BUFFER { char __far *pp; // x32 protected mode pointer; unsigned short segm; // real mode segment unsigned short offs; // real mode offset }; struct XR_BUFFER GetBufferAdr() { struct XR_BUFFER xr; asm { push es mov eax,0x250d // Get Transfer Buffer Address int 0x21 mov xr.offs,bx shr ebx,16 mov xr.segm,bx mov bx,es // seg mov DWord Ptr xr.pp,edx mov Word Ptr xr.pp+4,bx pop es } return xr; } int main() { struct XR_BUFFER x32_dos_buffer; struct RMI rmi; char local_buffer[64]; int i; x32_dos_buffer = GetBufferAdr(); fprintf(stderr, "Real(%04x:%04x), Prot(%04x:%08x)\n", x32_dos_buffer.segm, x32_dos_buffer.offs, FP_SEG(x32_dos_buffer.pp), FP_OFF(x32_dos_buffer)); rmi.irq_num = 0x21; // DOS interrupt rmi.eax = 0x5e00; // get machine name rmi.edx = x32_dos_buffer.offs; /* real mode offset of transfer buffer */ rmi.ds = x32_dos_buffer.segm; // real mode offset asm { mov eax,0x2511 lea edx,rmi int 0x21 } // now information is in transfer buffer // because the extender uses this buffer when doing I/O we copy // the contents to a local buffer first; for(i=0; i<64 && (local_buffer[i]=x32_dos_buffer.pp[i])!=0; ++i) ; printf("Name returned is %s\n", local_buffer); return 0; }//main ================== end CODE ===============


Feb 22 2005