
Capitulo 37 - unit dos

  Esta unidade  responsvel pela execuo das rotinas do DOS. Com ela torna-
se mais fcil a utilizao da maioria dos procedimentos de baixo nvel, 
e tambm ajuda bastante o operador em tarefas com arquivos pelo mtodo 
FILE HANDL. Para maiores explicaes a respeito deste processo, procure
um manual ou literatura a respeito do DOS. 

DOSVERSION - esta funo nos retorna em uma nica WORD, a verso dos Sis-
tema Operacional em uso. A parter baixa da funo retorna o nmero da verso
 e a parte alta o nmero da atualizao. Est disponvel na Unit Dos. Sua 
sintaxe:
DOSVERSION : WORD;
PROGRAM teste_dosversion;
USES DOS;
VAR
  ver : WORD;
BEGIN
  ver := DOSVERSION;
WRITELN (a verso deste Sistema Operacional, LO(ver), ., hi(ver));
END.

DISKFREE - esta funo retorna o nmero de bytes livres no drive passado 
como parmetro. Este deve ser um para o drive A; 2 para o B: e assim sucessi-
vamente. Se o drive passado como parmetro for 0, significa o drive corrente,
caso o valor retornado seja -1, indica que o drive passado como parmetro
foi invlido. Esata funo est disponvel na Unit DOS. Sua sintaxe:
DISKFREE (<drive> :BYTE : LONGINT;
Vejamos um exemplo:
PROGRAM teste_diskfree;
USES DOS;
BEGIN
  WRITELN (DISKFREE(1) DIV 1024 : 5, KB livres no drive A:);
  WRITELN (DISKFREE (2) DIV 1024 :5, KB livres no drive B: );
  WRITELN (DISKFREE(3) DIV 1024 : 5, KB livres no drive C: );
  WRITELN (DISKFREE(0) DIV 1024 :5,KB livres no drive corrent);
  READLN;
END.

DISKSIZE - esta funo nos retorna a quantidade de bytes total da unidade
de disco passada como parmetro. Este parmetro deve ser 1 para o drive A;
2 para o drive B; 3 para o drive C; e 0 para o drive corrente. No caso do 
drive passado como  parmetro seja invlido o resultado retornado pela funo
ser -1. Esta funo est disponvel na Unit DOS. sua sintaxe:
DISKSIZE (<drive> : BYTE) : LONGINT;
PROGRAM teste_disksize;
USES DOS;
VAR
  i : BYTE;
BEGIN
  FOR i := 0 TO 3 DO
    BEGIN
      IF DISKSIZE (i) > 0
        THEN
          BEGIN
            WRITE (DISKSIZE(i) : 10,bytes da capacidade no driv);
            IF i = 0
              THEN
                WRITELN (corrent)
              ELSE
                WRITELN (CHR(i + 64));
            END;
        END;
  READLN;
END.

ENVCOUNT - esta funo nos retorna o nmero de stringj contidas no ambientes
DOS. Estas strings so relativas s definies de PATH, COMSPEC, CONSTANTES
DO 
AMBIENTE, SETS ETC... Isto tudo depende logicamente de verso do DOS em uso.
Est disponvel na Unit DOS. Sua sintaxe:
ENVCOUNT : INTEGER;

ENVSTR - esta funo nos retorna a string do ambiente DOS correspondente 
ao ndice associado como parmetro. Est disponvel na Unit DOS. Se for
indicado um ndice a cima do nmero de string do ambiente DOS, ser retornada
uma stringa vazia. Sua sintaxe:
ENVSTR (<ind>) : INTEGER) : STRING;
Vejamos um exemplo que envolve estes ltimos comandos:
PROGRAM teste_envcount_envstr;
USES DOS;
VAR
  i : INTEGER;
BEGIN
  FOR i := 1 TO ENVCOUNT DO
    WRITELN (ENVSTR(i));
  READLN;
END.

GETENV - esta funo nos retorna o contedo da string passada como parmetro,
relativa ao ambiente DOS. Este contedo  o que estiver setado previamente
neste ambiente. Caso a stringa passada como parmetro no seja vlida para 
o ambiente DOS esta funo retornar uma string vazia. Est disponvel na
Unit DOS. Sua sintaxe:
GETENV (<ambiente> : STRING) : STRING;
PROGRAM teste_getenv;
USES DOS;
BEGIN
  WRITELN (GETENV (path));
  WRITELN (GETENV (comspe));
  READLN;
END.

EXEC - esta funo executa um comando passado como  parmetro para a funo
EXEC. O programa deve ter seu caminho completo inclusive a extenso do arquivo.
Caso seja necessrio passar parmetros, estes devem ser passados como segundo
argumento. Sua sintaxe:
EXEC (caminho, linha de comando : STRING);
  Para executar um comando interno do DOS constante do COMMAND.COM, ins-
tantaneamente, devemos faz-lo da seguinte forma:
EXEC (GETENV (COMSPE),/+ comando);
   recomendado que se utilize a funo SWAPVECTORS, a qual ser
anali-
sada mais adiante neste mesmo captulo, antes e depois do comando EXEC.
  O comando EXEC no troca a alocao de memria antes da execuo do programa.
Para que se resolva essa situao,  conveniente que se utilize a diretiva
de compilao $M.
  Veja bem o procedimento SWAPVECTORS.
  Vejamos um exemplo:
PROGRAM teste_exec;
{$M   $4000,0,0}     { 16 K STACK, no HEAP}
USES DOS;
VAR
  nomedoprograma, 
  linhadecomando : STRING;
BEGIN
  WRITE (programa a ser executado (todo o Path) : );
  READLN (nomedoprograma);
  WRITE (linha de comando a ser passada para ,program,
nomedoprograma, :);
  READLN(linhadecomando);
  WRITELN (executando...);
  SWAPVECTORS;
  EXEC (nomedoprograma, linhadecomando);
  SWAPVECTORS;
  WRITELN (...voltando do EXE);
  IF DOSERROR <> 0
    THEN
      WRITELN (DOS ERRO #,DOSERROR)
    ELSE
      WRITELN (bem sucedido.);
  READLN;
END.

DOSEXITCODE - esta funo retorna o cdigo de sada de um subprocesso. 
Se o resultado retornado for 0, indica um trmino regular, se for 1, indica
terminado por C, se for 2, houve um erro e caso tenha sido 3, indica trmino
de um programa residente. Sua sintaxe:
DOSEXICODE : WORD;
  Utilizando o mesmo exemplo anterior, vejamos como funciona esta funo:
PROGRAM teste_dosexitcode;
{$M $4000,0,0}     {16 K stack, no heap}
USES DOS;
VAR
  nomedoprograma, linhadecomando : STRING;
BEGIN
  WRITE (programa a ser executado(todo o Path) : );
  READLN (nomedoprograma);
  WRITE (linha de comando a ser passada para ,program,nomedoprograma,:);
  READLN (linhadecomando);
  WRITELN (executando ...);
  SWAPVECTORS;
  EXEC (nomedoprograma,linhadecomando);
  SWAPVECTORS;
  WRITELN (...voltando do EXE);
  IF DOSERROR <> 0
    THEN
      WRITELN (DOSERROR #, DOSERROR)
    ELSE
WRITELN (bem sucedido...,cdigo de ,retorn,DOSEXITCODE);
  READLN;
END.

FEXPAND - esta funo retorna uma string, contendo o nome do programa passado
como parmetro em sua totalidade. Sua sintaxe:
FEXPAND (path : PATHSTR) : PATHSTR;
  O tipo PATHSTR  predefinido na Unit DOS e corresponde  string [79];
PROGRAM teste_fexpand;
USES DOS;
VAR
  n : PATHSTR;
BEGIN  
  WRITELN (entre com o nome do programa a expandir);
  READLN (n);
  WRITELN (FEXPAND(n));
  READLN;
END.

FSEARCH - esta funo permite-nos procurar um determinado arquivo em uma 
lista de diretrios. Sua sintaxe:
FSEARCH (PATH : PATHSTR; lista : STRING) : PATHSTR;
  A lista de diretrios pode ser separada por ponto-e-vrgula (;). Se o 
arquivo especificado no for encontrado, a funo retornar uma string vazia.
A pesquisa  feita de qualquer forma, a partir do diretrio corrente.
  Vejamos um exemplo:
PROGRAM teste_fsearch;
USES DOS;
VAR
  n : PATHSTRT;
BEGIN
  WRITELN (entre com o nome do programa a procurar);
  READLN (n);
  WRITELN (FEXPAND(FSEARCH(n,GETENV(PATH))));
  READLN;
END.

FSPLIT - este procedimento explode o nome arquivo, passando como parmetro,
em 3 partes, o diretrio, o nome do arquivo e a extenso. Sua sintaxe:
FSPLIT (PATH : PATHSTR; VAR dir : DIRSTR; VAR nome : NAMASTR; VAR ext : EXTSTR);
  Os tipos PATHSTR, DIRSTR, NAMASTR E EXTSTR esto definidos na Unit DOS, da 
seguinte forma: 
TYPE 
  PATHSTR : STRING[79];
  DIRSTR : STRING[67];
  NAMESTR : STRING[08];
  EXTSTR : STRING[04];
PROGRAM teste_fsplit;
USES DOS;
VAR
  p : PATHSTR;
  d : DIRSTR;
  n : NAMESTR; 
  e : EXTSTR;
BEGIN
  WRITE (entre com o nome do arquivo: );
  READLN (p);
  FSPLIT(FSEARCH(p,GETENV(PATH)),d,n,e);
  WRITELN (o diretrio  ,d,o nom,n,e a extens,e);
  READLN;
END.

FINDFIRST - este procedimento permite-nos procurar um determinado arquivo,
especificando seu nome e seu atributo, isto em um diretrio especfico ou no
diretrio corrente. So passados como parmetros, 3 argumentos, o path, 
o atributo do arquivo e uma varivel do tipo Searchrec, predefinida na 
Unit DOS. Os possveis erros ser reportados na varivel DOSERROR, que retor-
nar 2 para diretrio no existente e 18 quando no existirem mais arquivos.
Sua sintaxe:
FINDFIRST(<caminho> : STRING; < atributo> : WORD; VAR <s> : SERACHREC);
VEjamos um exemplo:
PROGRAM teste_findfirst;
USES DOS;
VAR
  dirinfo : SEARCHREC;
BEGIN
  FINDFIRST(\*.*,$7,dirinfo);
  WRITELN;
  WRITE (sistema :);
  WRITELN (dirinfo.name);
  FINDFIRST(\*.*,DIRECTORY,dirinfo);
  WRITELN;
  WRITE (volume :);
  WRITELN (dirinfo.name);
  FINDFIRST(\*.*,$10,dirinfo);
  WRITELN;
  WRITE (diretrio :);
  WRITELN (dirinfo.name);
  READLN;
END.

  No exemplo acima, utilizamos um tipo predefinido pela Unit DOS, como segue:
TYPE
  SEARCHERC = RECORD
    fill : ARRAY [1..21] OF BYTE;
    attr : BYTE;
    time : LONGINT;
    size : LONGINT;
    name : STRING[12];
  END;
  Alm disto, nesta unidade temos predefinidas algumas constantes que podem
ser utilizadas no atributo so elas:
CONST
  ReadOnly = $01;  {apenas para leitura}
  Hidden = $02;   {escondido}
  SysFile = #04;   {arquivo de sistema}
  VolumeID = #08;   {nome de volume}
  Directory = $10;   {diretrio}
  Archive = $20;   {arquivo}
  AnyFile = $3F;   {qualquer arquivo}

FINDNEXT - este procedimento nos devolve a prxima entrada, de acordo com 
o nome de arquivo e tambm o atributo utilizado previamente na chamada 
do procedimento FINDFIRST, logo este procedimento dever ser precedido de
um procedimento FINDFIRST. Os possveis erros sero reportados na varivel
DOSERROR e esta retornar 18, indicando que no h mais arquivos. Sua sintaxe:
FINDNEXT (VAR <s> : SEARCHREC);
Vejamos um exemplo:
PROGRAM teste_findnext;
USES DOS;
VAR
  dirinfo : SEARCHREC;
  caminho : STRING;
  contador : WORD;
BEGIN
  contador := 0;
  FINDFIRST (\*.*,DIRECTORY,dirinfo);
  caminho := dirinfo.name;
  WRITELN;
  WHILE (DOSERROR = 0) AND (dirinfo.ATTR = DIRECTORY) DO
    BEGIN
      contador := contador + 1;
      WRITELN (contador, ,dirinfo.name);
      FINDNEXT(dirinfo);
    END;
  WRITELN;
  FINDFIRST(\ + caminho, DIRECTORY,dirinfo);
  FINDNEXT (dirinfo);
  WRITELN;
  WHILE (DOSERROR = 0) AND (dirinfo.ATTR = DIRECTORY) DO
    BEGIN
      contador := contador + 1;
      WRITELN (contador, , dirinfo.name);
      FINDNEXT(dirinfo);
    END;
  WRITELN;
  READLN;
END.

SETCBREAK - este procedimento permite que alteremos o estado da checagem
de CTRL-BREAK do Sistema Operacional. Sua sintaxe:
SETCBREAK (<BREAK> : BOOLEAN);
PROGRAM teste_setcbreak;
USES DOS;
CONST
  offon : ARRAY[BOOLEAN] OF STRING[3] = (OFF,ON);
VAR
  cb : BOOLEAN;
BEGIN
  GETCBREAK (cb);
  WRITELN (checagem de Control-Break est em ,offon[cb]);
  cb := NOT (cb);
  WRITELN (trocando Control_Break por,offon[cb]);
  SETCBREAK (cb);
  READLN;
END.

GETVERIFY - este procedimento retorna o estado do flag de verificao do 
sistema operacional. Quando desligado, as gravaes em discos no so veri-
ficadas, ao contrrio, quando ligado, todas as gravaes so verificadas.
Sua sintaxe:
GETVERIFY (VAR <v> : BOOLEAN);
Vamos a um exemplo:
PROGRAM teste_getverify;
USES DOS;
CONST
  offon : ARRAY[BOOLEAN] OF STRING[3] = (OFF,ON);
VAR
  v : BOOLEAN;
BEGIN
  GETVERIFY (v);
  WRITELN (a verificao de gravao est em:,offon[v]);
  READLN;
END.

SETVERIFY - este procedimento permite que alteremos o estado do flag de verifi-
cao do Sistema Operacional. Quando desligado, as gravaes em disco no
so verificadas, ao contrrio, quando ligado, todas as gravaes so verifi-
cadas. Sua sintaxe:
SETVERIFY (VAR<v> : BOOLEAN);
Vamos a um exemplo:
PROGRAM teste_setverify;
USES DOS;
CONST
  offon : ARRAY[BOOLEAN] OF STRING[3] = (OFF,ON);
VAR
  v : BOOLEAN;
BEGIN
  GETVERIFY (v);
  WRITELN (a verificao est em:,offon[v]);
  v := NOT(v);
  WRITELN(#13,#10,a verificao est send,trocada por:,offon[v]);
  SETVERIFY (v);
  WRITELN (#13,#10,agora a verificao d,gravao est em: ,offon[v]);
  READLN;
END.

GETDATE - este procedimento nos retorna a data corrente do sistema operacional.
Esta data tem 4 variveis, sendo elas: ano de 1980 a 2099; ms de 1 a 12;
dia de 1 a 31; e dia da semana de 0 a 6, sendo que o 0 corresponde ao do-
mingo. Sua sintaxe:
GETDATE (VAR <ano>, <ms>, <dia>, <dia_da_semana> : WORD);
Vejamos um exemplo:
PROGRAM teste_getdate;
USUS DOS;
CONST
  dias : ARRAY[0..6] OF STRING[3] = (DOM,SEG,TER,QU,QU,SEX,SAB);
VAR
  aa, mm, dd, d_s : WORD;
BEGIN
  GETDATE(aa,mm,dd,d_s);
  WRITELN (hoje  ,dias[d_s],, ,dd : 0,/,mm : 0,/,aa : 0);
  READLN;
END.

SETDATE - este procedimento permite-nos alterar a data corrente do Sistema
Operacional. Devem ser passadas como parmetro, 3 variveis, sendo elas:
ano de 1980 a 2099; ms de 1 a 12; dia de 1 a 31; caso a data passada como
parmetro seja invlida, a data do sistema ficar inalterada. Sua sintaxe:
SETDATE (<ano>, <ms>, <dia> : WORD);
Vejamos um exemplo:
PROGRAM teste_setdate;
USES DOS;
CONST
  dias : ARRAY[0..6] OF STRING[3] = (dom,seg,ter,qu,qu,sex,sab);
VAR
  aa, mm, dd, d_s, n_aa, n_mm, N-dd : WORD;
BEGIN
  GETDATE (aa,mm,dd,d_s);
  WRITELN (hoje  ,dias[d_s],, ,dd : 0,/,mm : 0, /,aa : 0);
  WRITE (digite o dia :);
  READLN (n_dd);
  WRITE (digite o ms: );
  READLN (n_mm);
  WRITE (digite o ano: );
  READLN (n_aa);
  SETDATE (n_aa,n_mm,n_aa);
  GETDATE (aa,mm,dd,d_s);
  IF (aa = n_aa) AND (mm = n_mm) AND (dd = n_dd)
    THEN
      WRITELN (hoje  , dias[d_s],, ,dd : 0, /,mm : 0,/, aa : 0);
  ELSE
    WRITELN (data invlida, a data anterior,no foi alterada!!! );
  READLN;
END.

GETTIME - este procedimento nos retorna a hora do sistema operacional 4 
variveis, sendo elas: hora de 0 a 23; minuto de 0 a 59; segundo de 0 a 59;
e centsimo de segundo de 0 a 99. Sua sintaxe:
GETTIME (VAR<hor>, <min>, <seg>, <cen> : WORD);
VEjamos um exemplo:
PROGRAM teste_gettime;
USES DOS, CRT;
VAR
  h, m, s, ds : WORD;
FUNCTION poezero(w : WORD) : STRING;
VAR
  s : STRING;
BEGIN
  STR(w : 0, s);
  IF LENGHT (s) = 1
    THEN
      s := 0 + s;
  poezero := s;
END;
          {programa principal}
BEGIN
  CLRSCR;
  GOTOXY (25,25);
  WRITE (tecle algo para continuar);
  REPEAT
    GETTIME (h,m,s,ds);
    GOTOXY (12,12);
    WRITE (hora atual  , poezero(h),:,poezero(m),:,poezero(s),.,
                 poezero(ds));
  UNTIL KEYPRESSED;
END.

SETTIME - este procedimento permite-nos alterar a hora do sistema operacional,
sendo permitido passar 4 variveis, sendo elas: hora de 0 a 23; minuto de 
0 a 59; segundo de 0 a 59; e centsimo de segundo de 0 a 99. Caso os argu-
mentos passados como parmetro sejam invlidos, o procedimento ser ignorado,
sendo mantida a hora anterior. 
SETTIME (<hor>, <min>, <seg>, <cen> : WORD);
Vejamos um exemplo:
PROGRAM teste_settime;
USES DOS;
VAR
  h, m, s, ds : WORD;
FUNCTION poezero (w : WORD) : STRING;
VAR
 s : STRING;
BEGIN
  STR(w : 0,s);
  IF LENGHT (s) = 1
    THEN
      s := 0 + s;
  poezero := s;
END;
        {programa principal}
BEGIN
  WRITE (digite a hora (0-23));
  READLN (h);
  WRITE (     minuto(0-59));
  READLN (m);
  WRITE (        segundo(0-59));
  READLN (s);
  WRITE (        centsimo de seg(0-99));
  READLN (ds);
  SETTIME (h,m,s,ds);
  GETTIME(h,m,s,ds);
  WRITE (hora atual  , poezero(h),:, poezero(m),:,poezero (s),
            .,poezero(ds));
  READLN;
END.

PACKTIME -  este procedimento permite-nos compactar data e hora em 4 bytes.
A data e hora devero estar em um registro especial, DATETIME predefinido 
na UNIT DOS, da seguinte forma:
DATETIME = RECORD
    YEAR, MONTH, DAY, HOUR, MIN, SEC : WORD;
  END;
  Este procedimento  normalmente utilizado quando temos a necessidade 
de atualizar a data e hora de criao de um arquivo. Este mesmo processo
 utilizado pelo sistema Operacional DOS, porm podemos tambm utiliz-lo
para outros fins que no sejam os de
