diff options
Diffstat (limited to 'v4.0/src/CMD/RESTORE/RTT3.C')
| -rw-r--r-- | v4.0/src/CMD/RESTORE/RTT3.C | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/v4.0/src/CMD/RESTORE/RTT3.C b/v4.0/src/CMD/RESTORE/RTT3.C new file mode 100644 index 0000000..e3edd0c --- /dev/null +++ b/v4.0/src/CMD/RESTORE/RTT3.C | |||
| @@ -0,0 +1,619 @@ | |||
| 1 | |||
| 2 | /*--------------------------------- | ||
| 3 | /* SOURCE FILE NAME: RTT3.C | ||
| 4 | /*--------------------------------- | ||
| 5 | /* 0 */ | ||
| 6 | |||
| 7 | #include "rt.h" | ||
| 8 | #include "rt1.h" | ||
| 9 | #include "rt2.h" | ||
| 10 | #include "direct.h" | ||
| 11 | #include "string.h" | ||
| 12 | #include "dos.h" /*;AN000;2*/ | ||
| 13 | #include "comsub.h" /* common subroutine def'n */ | ||
| 14 | #include "doscalls.h" | ||
| 15 | #include "error.h" | ||
| 16 | #include "process.h" /*;AN000;p972*/ | ||
| 17 | |||
| 18 | extern BYTE filename[12]; | ||
| 19 | extern BYTE destddir[MAXPATH+3]; | ||
| 20 | extern BYTE srcddir[MAXPATH+3]; | ||
| 21 | extern BYTE rtswitch; | ||
| 22 | extern BYTE control_flag; | ||
| 23 | extern BYTE control_flag2; | ||
| 24 | char far *buf_pointer; | ||
| 25 | char far *control_buf_pointer; | ||
| 26 | unsigned control_selector; | ||
| 27 | extern BYTE dest_file_spec[MAXFSPEC]; | ||
| 28 | extern unsigned dest_file_handle; | ||
| 29 | extern BYTE append_indicator; /*;AN000;2*/ | ||
| 30 | extern WORD original_append_func; /*;AN000;2*/ | ||
| 31 | extern struct subst_list sublist; /*;AN000;6 Message substitution list */ | ||
| 32 | extern char response_buff[5]; /*;AN000;6*/ | ||
| 33 | BYTE far *DBCS_ptr; /*;AN005;*/ | ||
| 34 | char got_dbcs_vector = FFALSE; /*;AN005;*/ | ||
| 35 | |||
| 36 | /***************** START OF SPECIFICATION ******************************** | ||
| 37 | /* | ||
| 38 | /* SUBROUTINE NAME : set_reset_test_flag | ||
| 39 | /* | ||
| 40 | /* DESCRIPTIVE NAME : to set a flag, reset a flag, or test a flag. | ||
| 41 | /* | ||
| 42 | /* FUNCTION: This subroutine is called when there is a need to set | ||
| 43 | /* a flag, reset a flag, or test a flag. | ||
| 44 | /* NOTES: | ||
| 45 | /* | ||
| 46 | /* INPUT: (PARAMETERS) | ||
| 47 | /* flag - the flag to be set, reset, or tested. | ||
| 48 | /* targetbt - the target bit to be set, reset, or tested. | ||
| 49 | /* choice - = 1 if want to set | ||
| 50 | /* = 2 if want to reset | ||
| 51 | /* = 3 if want to test | ||
| 52 | /* | ||
| 53 | /********************* END OF SPECIFICATIONS ********************************/ | ||
| 54 | int set_reset_test_flag(flag,targetbt,choice) | ||
| 55 | |||
| 56 | BYTE *flag; /*the flag to be tested against*/ | ||
| 57 | BYTE targetbt; /*the byte to be tested */ | ||
| 58 | int choice; | ||
| 59 | { | ||
| 60 | BYTE temp; | ||
| 61 | |||
| 62 | |||
| 63 | switch (choice) { | ||
| 64 | case SET: | ||
| 65 | *flag = *flag | targetbt; | ||
| 66 | break; | ||
| 67 | |||
| 68 | case RESET: | ||
| 69 | *flag = *flag & ~targetbt; | ||
| 70 | break; | ||
| 71 | |||
| 72 | case TEST: | ||
| 73 | temp = *flag & targetbt; | ||
| 74 | if (temp == 0) { | ||
| 75 | return(FALSE); /*the tested bit is off*/ | ||
| 76 | } | ||
| 77 | else { | ||
| 78 | return(TRUE); /*the tested bit is on */ | ||
| 79 | } | ||
| 80 | break; | ||
| 81 | |||
| 82 | default: | ||
| 83 | unexperror(UNEXPECTED); | ||
| 84 | break; | ||
| 85 | } /*end of switch */ | ||
| 86 | |||
| 87 | return(FALSE); /* wrw! */ | ||
| 88 | |||
| 89 | } | ||
| 90 | /***************** START OF SPECIFICATION ******************************** | ||
| 91 | /* | ||
| 92 | /* SUBROUTINE NAME : separate | ||
| 93 | /* | ||
| 94 | /* DESCRIPTIVE NAME : Separate the given input string into 3 parts; | ||
| 95 | /* which is the path, filename, file extension, and | ||
| 96 | /* file specification. | ||
| 97 | /* | ||
| 98 | /* FUNCTION: The subroutine searches the input string for the last '\', | ||
| 99 | /* which separates the path and file specification, and then | ||
| 100 | /* searches the file specification for '.', which separates | ||
| 101 | /* the filename and file extension. Also take care the | ||
| 102 | /* situation of the user enter '.' for file specification. | ||
| 103 | /* This subroutine also validate the file specification | ||
| 104 | /* and each path entered by the user by calling common | ||
| 105 | /* subroutine Comverflnm. | ||
| 106 | /* | ||
| 107 | /* NOTE: The input string must start with '\' | ||
| 108 | /* All the output string are terminated by 00h | ||
| 109 | /* | ||
| 110 | /* INPUT: (PARAMETERS) | ||
| 111 | /* instring - input string to be separated into path, filename, | ||
| 112 | /* and file extension. | ||
| 113 | /* | ||
| 114 | /* OUTPUT: | ||
| 115 | /* path - output path name, always starts with '\' and not end | ||
| 116 | /* with '\' | ||
| 117 | /* filename - output file name | ||
| 118 | /* fileext - output file extension | ||
| 119 | /* filespec - output file name and file extension | ||
| 120 | /* | ||
| 121 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 122 | void separate(instring,path,filename,fileext,filespec) | ||
| 123 | BYTE *instring; /* point to beginning of input string */ | ||
| 124 | BYTE *path; /* point to beginning of path string */ | ||
| 125 | BYTE *filename; /* point to beginning of file name */ | ||
| 126 | BYTE *fileext; /* point to beginning of file ext. */ | ||
| 127 | BYTE *filespec; /* point to beginning of file spec */ | ||
| 128 | { | ||
| 129 | BYTE *iptr; /* working pointer */ | ||
| 130 | BYTE *fptr; /* working pointer */ | ||
| 131 | WORD i; /*;AN005;*/ | ||
| 132 | |||
| 133 | /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
| 134 | /* Find last non-DBCS backslash character */ | ||
| 135 | /* fptr = com_strrchr(instring,'\\'); /*;AN000;p2532*/ | ||
| 136 | |||
| 137 | for ( /*;AN005;*/ | ||
| 138 | i=strlen(instring); /*;AN005;*/ | ||
| 139 | (i>=0) && (!chek_DBCS(instring,i,'\\')); /*;AN005;*/ | ||
| 140 | i-- /*;AN005;*/ | ||
| 141 | ) /*;AN005;*/ | ||
| 142 | {}; /*;AN005;*/ | ||
| 143 | |||
| 144 | fptr = instring + i; /*;AN005;*/ | ||
| 145 | /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | ||
| 146 | |||
| 147 | if (fptr!=instring || instring[0] == '\\') | ||
| 148 | { | ||
| 149 | *fptr = NULLC; /*;AC000;*/ | ||
| 150 | strcpy(path, instring); | ||
| 151 | if (path[0] == NULLC) | ||
| 152 | strcpy(path,"\\"); | ||
| 153 | *fptr = '\\'; | ||
| 154 | ++fptr; | ||
| 155 | strcpy(filespec, fptr); | ||
| 156 | |||
| 157 | if (filespec[0] == '.' && filespec[1] == NULLC) | ||
| 158 | { | ||
| 159 | strcpy(filename, "*"); | ||
| 160 | strcpy(fileext, "*"); | ||
| 161 | strcpy(filespec, "*.*"); | ||
| 162 | } | ||
| 163 | else | ||
| 164 | { /*else if filespec is not '.'*/ | ||
| 165 | for (iptr = fptr; *iptr!='.' && *iptr != NULLC; ++iptr); | ||
| 166 | |||
| 167 | if (*iptr == '.') | ||
| 168 | { | ||
| 169 | *iptr = NULLC; | ||
| 170 | strcpy(filename, fptr); | ||
| 171 | *iptr = '.'; | ||
| 172 | |||
| 173 | iptr = iptr+1; | ||
| 174 | strcpy(fileext, iptr); | ||
| 175 | } | ||
| 176 | else | ||
| 177 | { | ||
| 178 | strcpy(filename, filespec); | ||
| 179 | *fileext = NULLC; | ||
| 180 | } | ||
| 181 | |||
| 182 | } | ||
| 183 | |||
| 184 | } | ||
| 185 | else | ||
| 186 | {} | ||
| 187 | |||
| 188 | return; | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 192 | |||
| 193 | |||
| 194 | |||
| 195 | /***************** START OF SPECIFICATION ******************************** | ||
| 196 | /* | ||
| 197 | /* SUBROUTINE NAME : initbuf | ||
| 198 | /* | ||
| 199 | /* DESCRIPTIVE NAME : Initialize buffer for reading and writting. | ||
| 200 | /* | ||
| 201 | /* FUNCTION: Allocate up to 64 K bytes buffer for reading and writing | ||
| 202 | /* data, and make sure its size is divisible by the sector | ||
| 203 | /* size of the restore drive. | ||
| 204 | /* | ||
| 205 | /* NOTES: | ||
| 206 | /* | ||
| 207 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 208 | |||
| 209 | void initbuf(bufsize_long) | ||
| 210 | DWORD *bufsize_long; | ||
| 211 | { | ||
| 212 | unsigned bufsize; | ||
| 213 | WORD selector; | ||
| 214 | WORD retcode; | ||
| 215 | |||
| 216 | bufsize = MAXBUF; /*64K-1 */ | ||
| 217 | /*do while allocate bufsize fail, bufsize = bufsize - DOWNSIZE*/ | ||
| 218 | for (;;) { | ||
| 219 | retcode = DOSALLOCSEG( (unsigned ) bufsize, /*buf length */ | ||
| 220 | ( unsigned far * ) &selector, /* buf pointer*/ | ||
| 221 | ( unsigned) 0 ); /* no sharing */ | ||
| 222 | if ( retcode != 0) | ||
| 223 | { | ||
| 224 | if (bufsize > DOWNSIZE) | ||
| 225 | bufsize = bufsize - DOWNSIZE; | ||
| 226 | else | ||
| 227 | break; | ||
| 228 | } | ||
| 229 | else | ||
| 230 | break; | ||
| 231 | } | ||
| 232 | if (bufsize != 0 && bufsize <= DOWNSIZE ) { | ||
| 233 | display_it(INSUFFICIENT_MEMORY,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG);/*;AN000;6*/ | ||
| 234 | usererror(INSUFMEM); | ||
| 235 | } | ||
| 236 | |||
| 237 | FP_SEG( buf_pointer ) = selector; | ||
| 238 | FP_OFF( buf_pointer ) = 0 ; | ||
| 239 | |||
| 240 | if (bufsize == 0) | ||
| 241 | *bufsize_long = (DWORD)MAXBUF; | ||
| 242 | else | ||
| 243 | *bufsize_long = (DWORD)bufsize; | ||
| 244 | } /*end of subroutine*/ | ||
| 245 | |||
| 246 | /***************** START OF SPECIFICATION ******************************** | ||
| 247 | /* | ||
| 248 | /* SUBROUTINE NAME : init_control_buf | ||
| 249 | /* | ||
| 250 | /* DESCRIPTIVE NAME : Initialize buffer for control.XXX. | ||
| 251 | /* | ||
| 252 | /* FUNCTION: Allocate buffer for reading in control.xxx | ||
| 253 | /* | ||
| 254 | /* OUTPUT: | ||
| 255 | /* control_bufsize - the size of buffer | ||
| 256 | /* | ||
| 257 | /* | ||
| 258 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 259 | void init_control_buf(control_file_len,control_bufsize) /* !wrw */ | ||
| 260 | DWORD control_file_len; /* !wrw */ | ||
| 261 | unsigned int *control_bufsize; /* !wrw */ | ||
| 262 | { /* !wrw */ | ||
| 263 | unsigned bufsize; /* !wrw */ | ||
| 264 | WORD retcode; /* !wrw */ | ||
| 265 | |||
| 266 | bufsize = 3072; /* !wrw */ | ||
| 267 | |||
| 268 | |||
| 269 | retcode = DOSALLOCSEG( (unsigned ) bufsize, /* !wrw */ | ||
| 270 | ( unsigned far * ) &control_selector, /* !wrw */ | ||
| 271 | ( unsigned) 0 ); /* !wrw */ | ||
| 272 | |||
| 273 | |||
| 274 | if ( retcode != 0) /* If there is insufficient memory /* !wrw */ | ||
| 275 | { /* !wrw */ | ||
| 276 | display_it(INSUFFICIENT_MEMORY,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 277 | usererror(INSUFMEM); | ||
| 278 | } /* !wrw */ | ||
| 279 | |||
| 280 | FP_SEG( control_buf_pointer ) = control_selector; /* !wrw */ | ||
| 281 | FP_OFF( control_buf_pointer ) = 0 ; /* !wrw */ | ||
| 282 | |||
| 283 | *control_bufsize = bufsize; /* !wrw */ | ||
| 284 | |||
| 285 | } /*end of subroutine*/ /* !wrw */ | ||
| 286 | |||
| 287 | /***************** START OF SPECIFICATION ******************************** | ||
| 288 | /* | ||
| 289 | /* SUBROUTINE NAME : unexperror | ||
| 290 | /* | ||
| 291 | /* DESCRIPTIVE NAME : exit the program because of something really bad | ||
| 292 | /* occures | ||
| 293 | /* | ||
| 294 | /* FUNCTION: Exit the program because of unexpected error | ||
| 295 | /* | ||
| 296 | /* | ||
| 297 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 298 | void unexperror(retcode) | ||
| 299 | WORD retcode; | ||
| 300 | { | ||
| 301 | exit_routine(retcode); | ||
| 302 | return; | ||
| 303 | } | ||
| 304 | |||
| 305 | /***************** START OF SPECIFICATION ******************************** | ||
| 306 | /* | ||
| 307 | /* SUBROUTINE NAME : usererror | ||
| 308 | /* | ||
| 309 | /* DESCRIPTIVE NAME : exit the program because of a user error | ||
| 310 | /* | ||
| 311 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 312 | void usererror(retcode) | ||
| 313 | WORD retcode; | ||
| 314 | { | ||
| 315 | unexperror(retcode); | ||
| 316 | return; | ||
| 317 | } | ||
| 318 | |||
| 319 | /***************** START OF SPECIFICATION ******************************** | ||
| 320 | /* | ||
| 321 | /* SUBROUTINE NAME : exit_routine | ||
| 322 | /* | ||
| 323 | /* DESCRIPTIVE NAME : exit the program | ||
| 324 | /* | ||
| 325 | /* FUNCTION: 1. output msg if there is a sharing error. | ||
| 326 | /* 2. if PCDOS, convert return codes to error levels | ||
| 327 | /* 3. exit the program | ||
| 328 | /* | ||
| 329 | /* NOTES: | ||
| 330 | /* | ||
| 331 | /* INPUT: (PARAMETERS) | ||
| 332 | /* retcode - the reason of error | ||
| 333 | /* | ||
| 334 | /* | ||
| 335 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 336 | void exit_routine(retcode) | ||
| 337 | WORD retcode; | ||
| 338 | { | ||
| 339 | union REGS regs; /*;AN000;2*/ | ||
| 340 | |||
| 341 | chdir (destddir); | ||
| 342 | |||
| 343 | chdir (srcddir); | ||
| 344 | |||
| 345 | /* if flag indicates there is a SHAREERROR */ | ||
| 346 | if (retcode == NORMAL && | ||
| 347 | set_reset_test_flag(&control_flag,SHARERROR,TEST)==TRUE) | ||
| 348 | retcode = SHARERR; | ||
| 349 | |||
| 350 | switch(retcode) | ||
| 351 | { | ||
| 352 | case NORMAL: retcode = PC_NORMAL; | ||
| 353 | break; | ||
| 354 | case NOFILES: retcode = PC_NOFILES; | ||
| 355 | break; | ||
| 356 | case SHARERR: retcode = PC_SHARERR; | ||
| 357 | break; | ||
| 358 | case TUSER: retcode = PC_TUSER; | ||
| 359 | break; | ||
| 360 | default: retcode = PC_OTHER; | ||
| 361 | break; | ||
| 362 | } /* end switch */ | ||
| 363 | |||
| 364 | |||
| 365 | if (append_indicator == DOS_APPEND) /*;AN000;2 If append /x was reset*/ | ||
| 366 | { /*;AN000;2*/ | ||
| 367 | regs.x.ax = SET_STATE; /*;AN000;2*/ | ||
| 368 | regs.x.bx = original_append_func; /*;AN000;2*/ | ||
| 369 | int86(0x2f,®s,®s); /*;AN000;2*/ | ||
| 370 | } /*;AN000;2*/ | ||
| 371 | |||
| 372 | exit(retcode); /*;AN000;p972*/ | ||
| 373 | |||
| 374 | } | ||
| 375 | /***************** START OF SPECIFICATION ******************************** | ||
| 376 | /* | ||
| 377 | /* SUBROUTINE NAME : signal_handler_routine | ||
| 378 | /* | ||
| 379 | /* DESCRIPTIVE NAME : handle the situation that the user terminate | ||
| 380 | /* the program by Control-break. | ||
| 381 | /* | ||
| 382 | /* FUNCTION: This subroutine change the directory of the | ||
| 383 | /* destination disk back to the original directory. | ||
| 384 | /* If there is a file in the middle of restoring, close | ||
| 385 | /* the file, deleted the partially restored file, and | ||
| 386 | /* output a message. | ||
| 387 | /* Then exit with error level TUSER. | ||
| 388 | /* | ||
| 389 | /* | ||
| 390 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 391 | void pascal far signal_handler_routine() | ||
| 392 | { | ||
| 393 | WORD retcode; | ||
| 394 | |||
| 395 | DWORD dw = 0L; /* reserved double word*/ | ||
| 396 | |||
| 397 | /*change dir to the original directory of the destination disk*/ | ||
| 398 | |||
| 399 | /**************************************************************/ | ||
| 400 | /*if PARTIAL flag is on, close and delete the destination file*/ | ||
| 401 | /**************************************************************/ | ||
| 402 | if (set_reset_test_flag(&control_flag,PARTIAL,TEST) == TRUE) { | ||
| 403 | /* close the partially completed destination file*/ | ||
| 404 | DOSCLOSE(dest_file_handle); | ||
| 405 | /* delete the partially completed destination file*/ | ||
| 406 | if ((retcode = DOSDELETE((char far *) dest_file_spec, dw)) != 0) { | ||
| 407 | /*set file mode to 0*/ | ||
| 408 | if ((retcode = DOSSETFILEMODE((char far *)dest_file_spec, | ||
| 409 | (unsigned) 0x00, dw)) != 0) | ||
| 410 | { | ||
| 411 | com_msg(retcode); | ||
| 412 | unexperror(retcode); | ||
| 413 | } | ||
| 414 | /* delete the partially completed destination file*/ | ||
| 415 | if ((retcode = DOSDELETE((char far *) dest_file_spec, dw)) != 0) { | ||
| 416 | com_msg(retcode); | ||
| 417 | unexperror(retcode); | ||
| 418 | } | ||
| 419 | } | ||
| 420 | display_it(LAST_FILE_NOT_RESTORED,STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 421 | } | ||
| 422 | exit_routine(TUSER); | ||
| 423 | |||
| 424 | } /* end of signal_handler*/ | ||
| 425 | |||
| 426 | /************************************************************/ | ||
| 427 | /* | ||
| 428 | /* SUBROUTINE NAME: display_it (added for DOS 4.00) | ||
| 429 | /* | ||
| 430 | /* SUBROUTINE FUNCTION: | ||
| 431 | /* Display the requested message to the standard output device. | ||
| 432 | /* | ||
| 433 | /* INPUT: | ||
| 434 | /* 1) (WORD) Number of the message to be displayed. | ||
| 435 | /* 2) (WORD) Handle to be written to. | ||
| 436 | /* 3) (WORD) Substitution Count | ||
| 437 | /* 4) (WORD) Flag indicating user should "Strike any key..." | ||
| 438 | /* | ||
| 439 | /* OUTPUT: | ||
| 440 | /* The message corresponding to the requested msg number will | ||
| 441 | /* be written to the requested handle. If requested, substitution | ||
| 442 | /* text will be inserted as required. The Substitution List | ||
| 443 | /* is global and, if used, will be initialized by DISPLAY_MSG | ||
| 444 | /* before calling this routine. | ||
| 445 | /* | ||
| 446 | /* NORMAL EXIT: | ||
| 447 | /* Message will be successfully written to requested handle. | ||
| 448 | /* | ||
| 449 | /* ERROR EXIT: | ||
| 450 | /* None. Note that theoretically an error can be returned from | ||
| 451 | /* SYSDISPMSG, but there is nothing that the application can do. | ||
| 452 | /* | ||
| 453 | /* | ||
| 454 | /************************************************************/ | ||
| 455 | #define CLASS -1 /* Goes in DH register */ /*;AN000;6*/ | ||
| 456 | #define NUL_POINTER 0 /* Pointer to nothing */ /*;AN000;6*/ | ||
| 457 | |||
| 458 | void display_it(msg_number,handle,subst_count,waitflag,class) /*;AN000;6*/ | ||
| 459 | |||
| 460 | WORD msg_number; /*;AN000;6*/ | ||
| 461 | WORD handle; /*;AN000;6*/ | ||
| 462 | WORD subst_count; /*;AN000;6*/ | ||
| 463 | WORD waitflag; /*;AN000;6*/ | ||
| 464 | BYTE class; /*;AN000;6*/ | ||
| 465 | { /*;AN000;6*/ | ||
| 466 | union REGS reg; /*;AN000;6*/ | ||
| 467 | |||
| 468 | reg.x.ax = msg_number; /*;AN000;6*/ | ||
| 469 | reg.x.bx = handle; /*;AN000;6*/ | ||
| 470 | reg.x.cx = subst_count; /*;AN000;6*/ | ||
| 471 | reg.h.dh = class; /*;AN000;6*/ | ||
| 472 | reg.h.dl = (BYTE)waitflag; /*;AN000;6*/ | ||
| 473 | reg.x.di = (BYTE)&response_buff[0]; /*;AN000;6*/ | ||
| 474 | reg.x.si = (WORD)(char far *)&sublist; /*;AN000;6*/ | ||
| 475 | |||
| 476 | sysdispmsg(®,®); /*;AN000;6*/ | ||
| 477 | response_buff[0] = reg.h.al; /* User input */ /*;AN000;6*/ | ||
| 478 | |||
| 479 | return; /*;AN000;6 */ | ||
| 480 | } /*;AN000;6 */ | ||
| 481 | /***************** START OF SPECIFICATION ******************************** | ||
| 482 | /* | ||
| 483 | /* SUBROUTINE NAME : com_msg | ||
| 484 | /* | ||
| 485 | /* DESCRIPTIVE NAME : the routine to output a message according to | ||
| 486 | /* the return codes returned from API calls. | ||
| 487 | /* | ||
| 488 | /* FUNCTION: 1. if CP/DOS, then call rctomid | ||
| 489 | /* | ||
| 490 | /* NOTES: | ||
| 491 | /* | ||
| 492 | /* INPUT: (PARAMETERS) | ||
| 493 | /* retcode - return code used to call rctomid | ||
| 494 | /* | ||
| 495 | /* | ||
| 496 | /********************** END OF SPECIFICATIONS *******************************/ | ||
| 497 | void com_msg(retcode) | ||
| 498 | WORD retcode; | ||
| 499 | { | ||
| 500 | /* Was IF CPDOS */ | ||
| 501 | display_it(rctomid(retcode),STND_ERR_DEV,0,NO_RESPTYPE,(BYTE)UTIL_MSG); /*;AN000;6*/ | ||
| 502 | |||
| 503 | return; | ||
| 504 | |||
| 505 | } | ||
| 506 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 507 | /* */ | ||
| 508 | /* Subroutine Name: chek_DBCS() */ | ||
| 509 | /* */ | ||
| 510 | /* (Ripped off and Revised from ATTRIB.C) */ | ||
| 511 | /* */ | ||
| 512 | /* Subroutine Function: */ | ||
| 513 | /* Given an array and a position in the array, check if the character */ | ||
| 514 | /* is a non-DBCS character. */ | ||
| 515 | /* */ | ||
| 516 | /* Input: array, character position, character */ | ||
| 517 | /* */ | ||
| 518 | /* Output: TRUE - if array[position-1] != DBCS character AND */ | ||
| 519 | /* array[position] == character. */ | ||
| 520 | /* FALSE - otherwise */ | ||
| 521 | /* */ | ||
| 522 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 523 | WORD chek_DBCS(array,position,character) /*;AN005;*/ | ||
| 524 | char *array; /*;AN005;*/ | ||
| 525 | WORD position; /*;AN005;*/ | ||
| 526 | char character; /*;AN005;*/ | ||
| 527 | { /*;AN005;*/ | ||
| 528 | BYTE far *ptr; /*;AN005;*/ | ||
| 529 | WORD i; /*;AN005;*/ | ||
| 530 | char c; /*;AN005;*/ | ||
| 531 | char darray[128]; /* DBCS array, put "D" in every position*/ /*;AN005;*/ | ||
| 532 | /* that corresponds to the first byte */ | ||
| 533 | /* of a DBCS character. */ | ||
| 534 | if (!got_dbcs_vector) /*;AN005;*/ | ||
| 535 | Get_DBCS_vector(); /*;AN005;*/ | ||
| 536 | |||
| 537 | for (i=0;i<128;i++) /*;AN005;*/ | ||
| 538 | darray[i] = ' '; /*;AN005;*/ | ||
| 539 | |||
| 540 | /* Check each character, starting with the first in string, for DBCS */ | ||
| 541 | /* characters and mark each with a "D" in the corresponding darray. */ | ||
| 542 | for (i=0;i<position;i++) /*;AN005;*/ | ||
| 543 | { /*;AN005;*/ | ||
| 544 | c = array[i]; /*;AN005;*/ | ||
| 545 | |||
| 546 | /* look thru DBCS table to determine if character is first byte */ | ||
| 547 | /* of a double byte character */ | ||
| 548 | for (ptr=DBCS_ptr; (WORD)*(WORD far *)ptr != 0; ptr += 2) /*;AN005;*/ | ||
| 549 | { /*;AN005;*/ | ||
| 550 | |||
| 551 | /* check if byte is within range values of DOS DBCS table */ | ||
| 552 | if (c >= *ptr && c <= *(ptr+1)) /*;AN005;*/ | ||
| 553 | { /*;AN005;*/ | ||
| 554 | darray[i] = 'D'; /*;AN005;*/ | ||
| 555 | i++; /* skip over second byte of DBCS */ /*;AN005;*/ | ||
| 556 | break; /*;AN005;*/ | ||
| 557 | } /*;AN005;*/ | ||
| 558 | } /*;AN005;*/ | ||
| 559 | } /*;AN005;*/ | ||
| 560 | |||
| 561 | /* if character is not DBCS then check to see if it is == to character */ | ||
| 562 | if (darray[position-1] != 'D' && character == array[position]) /*;AN005;*/ | ||
| 563 | return (TTRUE); /*;AN005;*/ | ||
| 564 | else /*;AN005;*/ | ||
| 565 | return (FFALSE); /*;AN005;*/ | ||
| 566 | } /*;AN005;*/ | ||
| 567 | |||
| 568 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 569 | /* */ | ||
| 570 | /* Subroutine Name: Get_DBCS_vector() */ | ||
| 571 | /* */ | ||
| 572 | /* Subroutine Function: */ | ||
| 573 | /* Gets the double-byte table vector. */ | ||
| 574 | /* Puts it in global variable DBCS_ptr */ | ||
| 575 | /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ | ||
| 576 | void Get_DBCS_vector() /*;AN005;*/ | ||
| 577 | { /*;AN005;*/ | ||
| 578 | union REGS inregs,outregs; /*;AN005;*/ | ||
| 579 | struct SREGS segregs; /*;AN005;*/ | ||
| 580 | char fix_es_reg[2]; /*;AN005;*/ | ||
| 581 | WORD *ptr; /*;AN005;*/ | ||
| 582 | DWORD far *addr_ptr; /*;AN005;*/ | ||
| 583 | WORD *buffer; /*;AN005;*/ | ||
| 584 | |||
| 585 | /***********************************/ | ||
| 586 | /* Allocate a buffer */ | ||
| 587 | /***********************************/ | ||
| 588 | inregs.x.ax = 0x4800; /* Allocate */ /*;AN005;*/ | ||
| 589 | inregs.x.bx = 1; /* Num paragraphs */ /*;AN005;*/ | ||
| 590 | intdos(&inregs,&outregs); /* Int 21h */ /*;AN005;*/ | ||
| 591 | buffer = (WORD *)outregs.x.ax; /* Segment of buffer */ /*;AN005;*/ | ||
| 592 | |||
| 593 | inregs.x.ax = 0x6507; /* get extended country info */ /*;AN005;*/ | ||
| 594 | inregs.x.bx = 0xffff; /* use active code page */ /*;AN005;*/ | ||
| 595 | inregs.x.cx = 5; /* 5 bytes of return data */ /*;AN005;*/ | ||
| 596 | inregs.x.dx = 0xffff; /* use default country */ /*;AN005;*/ | ||
| 597 | inregs.x.di = 0; /* buffer offset */ /*;AN005;*/ | ||
| 598 | segregs.es = (WORD)buffer; /* buffer segment */ /*;AN005;*/ | ||
| 599 | segregs.ds = (WORD)buffer; /* buffer segment */ /*;AN005;*/ | ||
| 600 | intdosx(&inregs,&outregs,&segregs); /*;AN005;*/ | ||
| 601 | strcpy(fix_es_reg,NUL); /*;AN005;*/ | ||
| 602 | |||
| 603 | outregs.x.di++; /* skip over id byte */ /*;AN005;*/ | ||
| 604 | |||
| 605 | /* make a far ptr from ES:[DI] */ | ||
| 606 | addr_ptr = 0; /*;AN005;*/ | ||
| 607 | ptr = (WORD *)&addr_ptr; /*;AN005;*/ | ||
| 608 | *ptr = (WORD)outregs.x.di; /* get offset */ /*;AN005;*/ | ||
| 609 | ptr++; /*;AN005;*/ | ||
| 610 | *ptr = (WORD)segregs.es; /* get segment */ /*;AN005;*/ | ||
| 611 | DBCS_ptr = (BYTE far *)*addr_ptr; /*;AN005;*/ | ||
| 612 | DBCS_ptr += 2; /* skip over table length */ /*;AN005;*/ | ||
| 613 | |||
| 614 | /* DBCS_ptr points to DBCS table */ | ||
| 615 | strcpy(fix_es_reg,NUL); /*;AN005;*/ | ||
| 616 | got_dbcs_vector = TTRUE; /*;AN005;*/ | ||
| 617 | return; /*;AN005;*/ | ||
| 618 | } /*;AN005;*/ | ||
| 619 | |||