├── COPYING ├── CRITICAL.ASM ├── DELETE.BAT ├── DISKCOPY.INI ├── EMS.ASM ├── HICRITCL.ASM ├── IO95 ├── BORLANDC │ ├── MKLIB.BAT │ └── MKTEST.BAT ├── DIR95.C ├── DIR95.H ├── ERRLIST ├── FILES ├── FIND95.C ├── FIND95.H ├── FLLPTH95.C ├── FOPEN95.C ├── GETCWD95.C ├── HISTORY ├── IO95.H ├── IO95_LOC.H ├── L2S95.C ├── LICENSE ├── LICENSE.GPL ├── MAKEFILE ├── MKDIR95.C ├── OPEN95.C ├── README ├── REN95.C ├── STDIO95.H ├── T.CC ├── TAGS ├── TST.BAT ├── TST.OUT ├── TURBOC │ ├── MKLIB.BAT │ └── MKTEST.BAT ├── WIN95API.C ├── io95.bak └── makeio95.bat ├── LFNCHK.ASM ├── MAKEFILE ├── MOUSE.ASM ├── README ├── SWITCHCH.ASM ├── XMS.ASM ├── boot.h ├── cats ├── CATGETS.C ├── CATGETS.H ├── DB.C ├── DB.H ├── GET_LINE.C ├── makecats.bat └── makefile ├── critical.h ├── datgen.c ├── datgen.h ├── diskcopy.c ├── diskcopy.h ├── doc ├── copying.txt ├── diskcopy └── diskcopy.lsm ├── drive.c ├── drive.h ├── ems.h ├── exepath.c ├── exepath.h ├── fastcopy.c ├── fastcopy.h ├── indenter.bat ├── lfnapi.c ├── lfnapi.h ├── memtypes.c ├── memtypes.h ├── misc.h ├── mouse.h ├── nls ├── DISKCOPY.EN ├── diskcopy.FI ├── diskcopy.de ├── diskcopy.nl └── diskcopy.tr ├── nlsaspct.h ├── parser.c ├── parser.h ├── recovery.c ├── scanner.c ├── scanner.h ├── serialnm.c ├── serialnm.h ├── simplcpy.c ├── simplcpy.h ├── smdskcpy.c ├── smdskcpy.h ├── tdrvcpy.c ├── tdrvcpy.h ├── waitfinp.c ├── waitfinp.h └── xms.h /CRITICAL.ASM: -------------------------------------------------------------------------------- 1 | ; 2 | ; Critical.asm - critical error handler. 3 | ; Copyright (C) 2000, 2001 Imre Leber 4 | ; 5 | ; This program is free software; you can redistribute it and/or modify 6 | ; it under the terms of the GNU General Public License as published by 7 | ; the Free Software Foundation; either version 2 of the License, or 8 | ; (at your option) any later version. 9 | ; 10 | ; This program is distributed in the hope that it will be useful, 11 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ; GNU General Public License for more details. 14 | ; 15 | ; You should have received a copy of the GNU General Public License 16 | ; along with this program; if not, write to the Free Software 17 | ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | ; 19 | ; If you have any questions, comments, suggestions, or fixes please 20 | ; email me at: imre.leber@worlonline.be 21 | ; 22 | 23 | 24 | segment _DATA class=DATA 25 | 26 | handler DW 0 27 | 28 | segment _TEXT class=CODE 29 | 30 | ;************************************************************************ 31 | ;*** call_real_handler *** 32 | ;************************************************************************ 33 | ;*** Private function to encapsulate the critical error handler. *** 34 | ;************************************************************************ 35 | 36 | call_real_handler: 37 | push bx 38 | push cx 39 | push dx 40 | push si ;; Save all registers. 41 | push di 42 | push es 43 | push ss 44 | push ds 45 | 46 | sti 47 | mov dx, _DATA ;; Set data segment to _DATA. 48 | mov ds, dx 49 | 50 | and di, 0FFh ;; Prepare the parameter to 51 | xor al, al ;; give to the real handler. 52 | add ax, di 53 | 54 | push ax ;; Call real handler. 55 | call [handler] 56 | pop dx ;; take parameter from the stack. 57 | 58 | pop ds 59 | pop ss 60 | pop es ;; Restore all registers (except AX = retval.). 61 | pop di 62 | pop si 63 | pop dx 64 | pop cx 65 | pop bx 66 | iret 67 | 68 | ;************************************************************************ 69 | ;*** SetCriticalHandler *** 70 | ;************************************************************************ 71 | ;*** void SetCriticalHandler(int (*handler)(int status)); *** 72 | ;*** *** 73 | ;*** Installs the critical error handler and sets the routine to call *** 74 | ;*** to handler. *** 75 | ;************************************************************************ 76 | 77 | global _SetCriticalHandler 78 | _SetCriticalHandler: 79 | push bp 80 | mov bp, sp 81 | push es 82 | push ds 83 | 84 | mov ax, [bp+04h] ; Get real handler and 85 | mov [handler], ax ; save it. 86 | 87 | mov dx, call_real_handler 88 | push cs 89 | pop ds ; Install the new critical handler. 90 | mov ax, 2524h 91 | int 21h 92 | 93 | pop ds 94 | pop es 95 | pop bp 96 | ret 97 | 98 | %if 0 99 | ;************************************************************************** 100 | ;*** RenewCriticalHandler *** 101 | ;************************************************************************** 102 | ;*** void RenewCriticalHandler(int (*handler)(int status)); *** 103 | ;*** *** 104 | ;*** Sets the routine to call to handler. *** 105 | ;************************************************************************** 106 | 107 | global _RenewCriticalHandler 108 | _RenewCriticalHandler: 109 | push ds 110 | 111 | mov bx, sp 112 | mov ax, [ss:bx+04h] ; Save the newly given handler 113 | mov [handler], ax ; as the handler to call. 114 | 115 | pop ds 116 | ret 117 | 118 | %endif 119 | -------------------------------------------------------------------------------- /DELETE.BAT: -------------------------------------------------------------------------------- 1 | @if exist %1 del %1 -------------------------------------------------------------------------------- /DISKCOPY.INI: -------------------------------------------------------------------------------- 1 | # 2 | # If you don't want to use a configuration file, you can delete this file. 3 | # 4 | 5 | [- MEMORY -] 6 | DISK = YES 7 | XMS = YES 8 | EMS = YES 9 | 10 | [- OPTIONS -] 11 | AUDIBLE = NO 12 | VERIFY = NO 13 | INFORMATIVE = YeS # standard is NO 14 | OVERWRITE = NEVER 15 | AUTOEXIT = NO 16 | MODE = NORMAL 17 | ASKDISK = YES 18 | SPEED = FULL 19 | ASKTARGET = No # standard is YES 20 | SERIALNUMBER = UPDATE 21 | 22 | [- GENERATION -] 23 | USEDATFILE = NO 24 | 25 | -------------------------------------------------------------------------------- /EMS.ASM: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; EMS.ASM - routines to use Extended Memory from a DOS program. 3 | ;; 4 | ;; Copyright (C) 2000, 2001 Imre Leber. 5 | ;; 6 | ;; This program is free software; you can redistribute it and/or modify 7 | ;; it under the terms of the GNU General Public License as published by 8 | ;; the Free Software Foundation; either version 2 of the License, or 9 | ;; (at your option) any later version. 10 | ;; 11 | ;; This program is distributed in the hope that it will be useful, 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ;; GNU General Public License for more details. 15 | ;; 16 | ;; You should have recieved a copy of the GNU General Public License 17 | ;; along with this program; if not, write to the Free Software 18 | ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | ;; 20 | ;; If you have any questions, comments, suggestions, or fixes please 21 | ;; email me at: imre.leber@worlonline.be 22 | ;; 23 | ;; 24 | ;;************************************************************************* 25 | ;; Routines to use Epanded Memory from a DOS program. 26 | ;; 27 | ;; NOTE: translation from the EMS routines by Cliff Rhodes to NASM by 28 | ;; Imre Leber. 29 | ;; 30 | ;; The C version was released to the public domain by Cliff Rhodes with 31 | ;; no guarantees of any kind. 32 | ;; 33 | ;; The assembly version is hereby put under GNU General Public License by 34 | ;; Imre Leber. 35 | ;; 36 | ;;************************************************************************* 37 | ;; Last changed: 38 | ;; 39 | ;; april 16, 2001: Fixed situation where si and di not saved. 40 | ;; 41 | 42 | %assign EMS_INT 67h ;; EMS interrupt number. 43 | %assign EMS_VERSION 32h ;; Version 3.2 of EMS. 44 | %assign RES_VERSION 40h ;; At least version 4.0 to be resizable. 45 | 46 | ; EMS service codes. 47 | %assign EMSservice1 40h ;; Get EMS status. 48 | %assign EMSservice2 41h ;; Get segment address of page 0. 49 | %assign EMSservice3 42h ;; Get total number of expanded pages. 50 | %assign EMSservice4 43h ;; Get handle and assign pages to it. 51 | %assign EMSservice5 44h ;; Map a page into one of the page frames. 52 | %assign EMSservice6 45h ;; Close EMS handle. 53 | %assign EMSservice7 46h ;; Get the EMS version number. 54 | 55 | ;=============================== DATA ===================================== 56 | 57 | segment _DATA class=DATA 58 | 59 | %assign ID_LEN 8/2 60 | EMS_ID db "EMMXXXX0" ;; EMS identification string. 61 | 62 | ;=============================== CODE ===================================== 63 | 64 | segment _TEXT class=CODE 65 | 66 | ;========================================================================== 67 | ;=== EMSbaseaddress === 68 | ;========================================================================== 69 | ;=== unsigned int EMSbaseaddress(void); === 70 | ;=== === 71 | ;=== Determines if EMS present. If so returns base segment of EMS. === 72 | ;=== Returns 0 if EMS not available. The base segment is necessary === 73 | ;=== for mapping EMS memory pages into the user address space (see === 74 | ;=== EMSmap() below). === 75 | ;========================================================================== 76 | 77 | global _EMSbaseaddress 78 | _EMSbaseaddress: 79 | push es 80 | push si 81 | push di 82 | 83 | cld 84 | 85 | mov ax, 3567h 86 | int 21h 87 | 88 | mov si, EMS_ID 89 | mov cx, ID_LEN 90 | mov di, 10 ;; EMS_ID must be at offset 10 91 | 92 | repe cmpsw 93 | je .next 94 | 95 | xor ax, ax 96 | jmp short .EndOfProc 97 | 98 | .next: 99 | mov ah, EMSservice2 ;; Get page frame segment. 100 | int EMS_INT 101 | 102 | cmp ah, 0 103 | je .GotFrame 104 | 105 | xor ax, ax 106 | jmp short .EndOfProc 107 | 108 | .GotFrame: 109 | mov ax, bx 110 | 111 | .EndOfProc: 112 | pop di 113 | pop si 114 | pop es 115 | ret 116 | 117 | ;========================================================================== 118 | ;=== EMSversion === 119 | ;========================================================================== 120 | ;=== int EMSversion(void); === 121 | ;=== === 122 | ;=== Returns current EMS version, -1 if not found or obsolete. === 123 | ;========================================================================== 124 | 125 | global _EMSversion 126 | _EMSversion: 127 | 128 | mov ah, EMSservice7 129 | int EMS_INT 130 | 131 | cmp ah, 0 132 | jne .NotGood 133 | 134 | cmp al, EMS_VERSION 135 | jb .NotGood 136 | jmp short .EndOfProc 137 | 138 | .NotGood: 139 | mov ax, -1 140 | 141 | .EndOfProc: 142 | ret 143 | 144 | ;========================================================================== 145 | ;=== EMSstatus === 146 | ;========================================================================== 147 | ;=== int EMSstatus(void); === 148 | ;=== === 149 | ;=== Returns 0 if EMS system OK, -1 if not. === 150 | ;========================================================================== 151 | 152 | global _EMSstatus 153 | _EMSstatus: 154 | 155 | mov ah, EMSservice1 156 | int EMS_INT 157 | 158 | cmp ah, 0 159 | je .next1 160 | 161 | mov ax, -1 162 | jmp short .EndOfProc 163 | 164 | .next1: 165 | xor ax, ax 166 | 167 | .EndOfProc: 168 | ret 169 | 170 | ;========================================================================== 171 | ;=== EMSpages === 172 | ;========================================================================== 173 | ;=== int EMSpages(void); === 174 | ;=== === 175 | ;=== Returns number of free EMS pages (each page is 16k), -1 if error. === 176 | ;========================================================================== 177 | 178 | global _EMSpages 179 | _EMSpages: 180 | 181 | mov ah, EMSservice3 182 | int EMS_INT 183 | 184 | cmp ah, 0 185 | je .next 186 | 187 | mov ax, -1 188 | jmp short .EndOfProc 189 | 190 | .next: 191 | mov ax, bx 192 | 193 | .EndOfProc: 194 | ret 195 | 196 | ;========================================================================== 197 | ;=== EMSalloc === 198 | ;========================================================================== 199 | ;=== int EMSalloc(int pages); === 200 | ;=== === 201 | ;=== Returns handle to block of size pages or -1 if error. === 202 | ;=== === 203 | ;=== NOTE: always free any handles when you are done!. === 204 | ;========================================================================== 205 | 206 | global _EMSalloc 207 | _EMSalloc: 208 | mov bx, sp 209 | 210 | mov ah, EMSservice4 211 | mov bx, [ss:bx+02h] 212 | int EMS_INT 213 | 214 | cmp ah, 0 215 | je .next 216 | 217 | mov ax, -1 218 | jmp short .EndOfProc 219 | 220 | .next: 221 | mov ax, dx 222 | 223 | .EndOfProc: 224 | ret 225 | 226 | ;========================================================================== 227 | ;=== EMSfree === 228 | ;========================================================================== 229 | ;=== int EMSfree(int handle); === 230 | ;=== === 231 | ;=== Frees handle block, returns 0 if successful, -1 if error. === 232 | ;========================================================================== 233 | 234 | global _EMSfree 235 | _EMSfree: 236 | mov bx, sp 237 | 238 | mov ah, EMSservice6 239 | mov dx, [ss:bx+02h] 240 | int EMS_INT 241 | 242 | cmp ah, 0 243 | je .next 244 | 245 | mov ax, -1 246 | jmp short .EndOfProc 247 | 248 | .next: 249 | xor ax, ax 250 | 251 | .EndOfProc: 252 | ret 253 | 254 | ;============================================================================= 255 | ;=== EMSmap === 256 | ;============================================================================= 257 | ;=== int EMSmap(int bank, int handle, int page); === 258 | ;=== === 259 | ;=== Maps page of handle into bank. Returns 0 if successful, -1 if error. === 260 | ;=== Each handle controls 1 or more 16k pages of EMS memory. === 261 | ;=== There are four banks 0-3. bank 0 starts at the segment returned by === 262 | ;=== EMSbaseaddress(), bank 1 starts at that segment with offset 16k, etc. === 263 | ;============================================================================= 264 | 265 | global _EMSmap 266 | _EMSmap: 267 | push bp 268 | mov bp, sp 269 | 270 | mov ax, [bp+04h] ; bank. 271 | mov bx, [bp+08h] ; page. 272 | mov dx, [bp+06h] ; handle. 273 | mov ah, EMSservice5 274 | int EMS_INT 275 | 276 | cmp ah, 0 277 | je .EndOfProc 278 | 279 | mov ax, -1 280 | 281 | .EndOfProc: 282 | pop bp 283 | ret 284 | 285 | %if 0 286 | ;========================================================================= 287 | ;=== EMSResizable === 288 | ;========================================================================= 289 | ;=== int EMSResizable(); === 290 | ;=== === 291 | ;=== Returns wether the pages allocated for a certain handle can be === 292 | ;=== changed. === 293 | ;========================================================================= 294 | 295 | global _EMSResizable 296 | _EMSResizable: 297 | 298 | mov ah, EMSservice7 ;; Get version number, 299 | int EMS_INT 300 | 301 | cmp al, RES_VERSION ;; and see if it is at 302 | jb .NotSupported ;; least version 4.0. 303 | 304 | mov ax, 1 305 | jmp short .EndOfProc 306 | 307 | .NotSupported: 308 | xor ax, ax 309 | 310 | .EndOfProc: 311 | ret 312 | 313 | ;========================================================================= 314 | ;=== EMSResize === 315 | ;========================================================================= 316 | ;=== int EMSResize(int handle, int pages); === 317 | ;=== === 318 | ;=== Change the amount of pages allocated for a certain handle. === 319 | ;=== === 320 | ;=== Remark: check first wether this function is supported. === 321 | ;=== === 322 | ;=== Returns: 0 on success, -1 or error. === 323 | ;========================================================================= 324 | 325 | global _EMSResize 326 | _EMSResize: 327 | 328 | push bp 329 | mov bp, sp 330 | 331 | mov ah, 51h 332 | mov dx, [bp+04h] 333 | mov bx, [bp+06h] 334 | int EMS_INT 335 | 336 | cmp ah, 0 337 | je .next 338 | 339 | mov ax, -1 340 | jmp short .EndOfProc 341 | 342 | .next: 343 | xor ax, ax 344 | 345 | .EndOfProc: 346 | pop bp 347 | ret 348 | %endif 349 | -------------------------------------------------------------------------------- /HICRITCL.ASM: -------------------------------------------------------------------------------- 1 | ; 2 | ; hicritcl.asm - the effective critical handler for this application. 3 | ; Copyright (C) 2000, 2001 Imre Leber 4 | ; 5 | ; This program is free software; you can redistribute it and/or modify 6 | ; it under the terms of the GNU General Public License as published by 7 | ; the Free Software Foundation; either version 2 of the License, or 8 | ; (at your option) any later version. 9 | ; 10 | ; This program is distributed in the hope that it will be useful, 11 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ; GNU General Public License for more details. 14 | ; 15 | ; You should have received a copy of the GNU General Public License 16 | ; along with this program; if not, write to the Free Software 17 | ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | ; 19 | ; If you have any questions, comments, suggestions, or fixes please 20 | ; email me at: imre.leber@worlonline.be 21 | ; 22 | 23 | %assign FAIL 3 ;; fail on critical error. 24 | 25 | extern _SetCriticalHandler 26 | 27 | segment _DATA class=DATA 28 | 29 | CriterrOccured DB 0 ;; has there been a critical error. 30 | 31 | status DB 0 ;; status byte. 32 | cause DB 0 ;; cause of error. 33 | 34 | segment _TEXT class=CODE 35 | 36 | ;*********************************************************************** 37 | ;*** criticalhandler *** 38 | ;*********************************************************************** 39 | ;*** Our critical error handler. *** 40 | ;*** *** 41 | ;*** Remembers status and cause of critical error. *** 42 | ;*********************************************************************** 43 | 44 | criticalhandler: 45 | mov bx, sp 46 | mov ax, [ss:bx+02h] 47 | 48 | mov [status], ah ;; Save status byte. 49 | mov [cause], al ;; Save cause of error. 50 | mov [CriterrOccured], byte 1 ;; Remember that a critical 51 | ;; error has occured. 52 | mov ax, FAIL 53 | ret 54 | 55 | ;*********************************************************************** 56 | ;*** CriticalHandlerOn *** 57 | ;*********************************************************************** 58 | ;*** void CriticalHandlerOn(void); *** 59 | ;*** *** 60 | ;*** Installs our critical error handler. *** 61 | ;*********************************************************************** 62 | 63 | global _CriticalHandlerOn 64 | _CriticalHandlerOn: 65 | 66 | mov ax, criticalhandler ;; Point the real critical handler 67 | push ax ;; to our handler. 68 | call _SetCriticalHandler 69 | pop ax 70 | 71 | mov [CriterrOccured], byte 0 ;; Make sure that there is no pending 72 | ;; critical error. 73 | ret 74 | 75 | ;*********************************************************************** 76 | ;*** CriticalErrorOccured *** 77 | ;*********************************************************************** 78 | ;*** int CriticalErrorOccured(void); *** 79 | ;*** *** 80 | ;*** Returns wether there has been a critical error. *** 81 | ;*** *** 82 | ;*** Remark: can only be called once. *** 83 | ;*********************************************************************** 84 | 85 | global _CriticalErrorOccured 86 | _CriticalErrorOccured: 87 | 88 | xor ax, ax 89 | mov al, [CriterrOccured] ;; See if there hasn't been a critical 90 | ;; error. 91 | mov [CriterrOccured], byte 0 92 | ret 93 | 94 | %if 0 95 | ;*********************************************************************** 96 | ;*** GetCriticalCause *** 97 | ;*********************************************************************** 98 | ;*** int GetCriticalCause(void); *** 99 | ;*** *** 100 | ;*** Returns the cause of the critical error. *** 101 | ;*********************************************************************** 102 | 103 | global _GetCriticalCause 104 | _GetCriticalCause: 105 | 106 | xor ax, ax ;; Return critical error cause. 107 | mov al, [cause] 108 | ret 109 | 110 | ;*********************************************************************** 111 | ;*** GetCriticalStatus *** 112 | ;*********************************************************************** 113 | ;*** int GetCriticalStatus(void); *** 114 | ;*** *** 115 | ;*** Returns the status byte for the critical error. *** 116 | ;*********************************************************************** 117 | 118 | global _GetCriticalStatus 119 | _GetCriticalStatus: 120 | 121 | xor ax, ax 122 | mov al, [status] ;; Return status byte. 123 | ret 124 | %endif 125 | -------------------------------------------------------------------------------- /IO95/BORLANDC/MKLIB.BAT: -------------------------------------------------------------------------------- 1 | bcc -v -y -vi -c *.c >errlist 2 | del t.obj 3 | lib /c io95 -+ .\* , io95 4 | -------------------------------------------------------------------------------- /IO95/BORLANDC/MKTEST.BAT: -------------------------------------------------------------------------------- 1 | bcc -v -y -vi t.cc io95.lib 2 | -------------------------------------------------------------------------------- /IO95/DIR95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: DIR95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | dir - open/close/read/seek/tell 5 | 6 | POSIX.1 variant 7 | 8 | == For instance: 9 | DIR95 *dir; 10 | struct dirent95 *de; 11 | 12 | if((dir = opendir95(pathname)) != NULL) { 13 | while((de = readdir95(dir)) != NULL) 14 | printf("%ld. entry = \"%s\"\n", telldir95(dir), de->d_name); 15 | closedir95(dir); 16 | } 17 | == 18 | 19 | If the path starts with "\\\\" both backslashes remain; that 20 | gives some support for UNC path spec. 21 | 22 | $Log: not supported by cvs2svn $ 23 | Revision 1.2 2000/01/11 09:34:23 ska 24 | add: support Turbo C v2.01 25 | 26 | Revision 1.1 2000/01/11 09:10:08 ska 27 | Auto Check-in 28 | 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "dir95.h" 40 | #include "io95.h" 41 | 42 | #define PATTERN "\\*.*" /* search pattern */ 43 | #define MAXDRVLEN 2 44 | 45 | #ifndef offsetof 46 | #define offsetof(s,m) (size_t)&(((s *)0)->m) 47 | #endif 48 | 49 | #ifndef lint 50 | static char const rcsid[] = 51 | "$Id: DIR95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 52 | #endif 53 | 54 | 55 | /* 56 | * opendir 57 | */ 58 | 59 | DIR95 *opendir95(const char * const name) 60 | { 61 | register DIR95 *nd; 62 | char cwd[MAXPATH95 + 2048]; 63 | /* make sure that cwd can hold: 64 | 1) a path component 65 | 2) the string terminator 66 | 3) the drive spec 67 | 4) the "root" backslash 68 | 5) some room while constructing the fully-qualified path 69 | */ 70 | 71 | assert(name); 72 | 73 | if(!fullpath95(cwd, name, sizeof(cwd) - sizeof(PATTERN))) 74 | return NULL; 75 | 76 | assert(strlen(cwd) > 2); 77 | 78 | if(!cwd[3]) /* root */ 79 | strcpy(&cwd[2], PATTERN); 80 | else strcat(cwd, PATTERN); /* append the search pattern */ 81 | 82 | /* construct DIR95 */ 83 | if ((nd = (DIR95 *)malloc(sizeof(DIR95) + max(strlen(cwd), DTALEN - 84 | sizeof(DIR95) - offsetof(DIR95, dd_dta)))) == NULL) 85 | return NULL; 86 | 87 | strcpy(nd->dd_dir, cwd); 88 | 89 | /* perform the first search */ 90 | nd->dd_cnt = 1; /* force seekdir() to re-read directory */ 91 | seekdir95(nd, 0l); 92 | 93 | if (nd->dd_stat) { /* failed */ 94 | free((char *)nd); 95 | return NULL; 96 | } 97 | 98 | return nd; 99 | } 100 | 101 | 102 | struct dirent95 *readdir95(DIR95 * const dirp) 103 | { 104 | assert(dirp); 105 | if (dirp->dd_stat) /* already at end of directory */ 106 | return NULL; 107 | 108 | ++dirp->dd_cnt; /* keep track of read entries */ 109 | assert(dirp->dd_dta.ff_95.ff_longname[0]); 110 | strcpy(dirp->dd_de.d_name, dirp->dd_dta.ff_95.ff_longname); 111 | 112 | /* read ahead */ 113 | dirp->dd_stat = findnext95(&dirp->dd_dta); 114 | 115 | return &dirp->dd_de; 116 | } 117 | 118 | 119 | void closedir95(DIR95 * const dirp) 120 | { 121 | assert(dirp); 122 | findstop95(&dirp->dd_dta); 123 | free((char *)dirp); 124 | } 125 | 126 | 127 | void seekdir95(DIR95 * const dirp, long pos) 128 | { 129 | assert(dirp); 130 | if(dirp->dd_cnt > pos) { /* we seek backwards -> restart */ 131 | findstop95(&dirp->dd_dta); 132 | dirp->dd_stat = findfirst95(dirp->dd_dir, &dirp->dd_dta, 0x37); 133 | dirp->dd_cnt = 0; 134 | } 135 | 136 | while(dirp->dd_cnt < pos && !dirp->dd_stat) { 137 | dirp->dd_stat = findnext95(&dirp->dd_dta); 138 | ++dirp->dd_cnt; 139 | } 140 | } 141 | 142 | 143 | long telldir95(DIR95 * const dirp) 144 | { 145 | assert(dirp); 146 | return dirp->dd_cnt; 147 | } 148 | -------------------------------------------------------------------------------- /IO95/DIR95.H: -------------------------------------------------------------------------------- 1 | /* $Id: DIR95.H,v 1.1 2006-07-04 19:07:58 perditionc Exp $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | Declaration for the POSIX.1 opendir() family supporting 5 | Win95 LFN API (in addition to the standard DOS API) 6 | 7 | $Log: not supported by cvs2svn $ 8 | Revision 1.1 2000/01/11 09:10:09 ska 9 | Auto Check-in 10 | 11 | */ 12 | 13 | #ifndef _DIR95_h_ 14 | #define _DIR95_h_ 15 | 16 | #include 17 | #include "io95.h" 18 | #include "find95.h" 19 | 20 | 21 | struct dirent95 { 22 | 23 | /* long d_ino; */ 24 | /* unsigned short d_reclen; */ 25 | /* unsigned short d_namlen; */ 26 | 27 | char d_name[MAXNAME95+1]; 28 | }; 29 | 30 | typedef struct { 31 | long dd_cnt; /* for seekdir()/telldir() */ 32 | short dd_stat; /* status return from last lookup */ 33 | FF_Block95 dd_dta; /* disk transfer area for this dir. */ 34 | struct dirent95 dd_de; /* will be returned by readdir() */ 35 | char dd_dir[1]; /* fully-qualifed name of directory */ 36 | /* this member is dynamically extended that the name fits in 37 | there. 38 | Note: The DTA, which is active during the findfirst/findnext 39 | calls, is probably smaller than the "normal" size of 128 bytes. 40 | This should not cause any problems, as I see more than one 41 | implementations assuming this, that causes no crash. 42 | */ 43 | } DIR95; 44 | 45 | extern DIR95 *opendir95(const char * const); 46 | extern struct dirent95 *readdir95(DIR95 * const); 47 | extern long telldir95(DIR95 * const); 48 | extern void seekdir95(DIR95 * const, long); 49 | extern void closedir95(DIR95 * const); 50 | 51 | #define rewinddir95(dirp) seekdir95(dirp,0L) 52 | 53 | int getcurdir95(int drive, char * const dir); 54 | /* Retrieve current directory of drive. 55 | 56 | drive: 0 = current drive; 1 = A:; 2 = B: 57 | dir must point to a buffer large enough to recieve the path, one 58 | should allocate at least MAXPATH95 bytes. 59 | 60 | Return: 61 | -1: failure 62 | 0: success; *dir filled without drive/colon and leading backslash 63 | */ 64 | 65 | char * getdcwd95(int drive, char *buf, int buflen); 66 | /* Get current working directory of drive. 67 | 68 | drive: 0 = current drive; 1 = A:; 2 = B: 69 | 70 | If buf == NULL, buflen bytes will be allocated. 71 | If buf == NULL && buflen == 0, a buffer will be allocated, that is 72 | as small as the directory string will fit in. 73 | If buf != NULL && buflen less than the length of the directory 74 | string, a failure occurs and 'errno' is set to ERANGE. 75 | 76 | The allocated buffer should be free()'ed by the programmer. 77 | 78 | Return: 79 | == NULL: failure 80 | != NULL: buf or allocated buffer: success 81 | */ 82 | 83 | char * getcwd95(char *buf, int buflen); 84 | /* Return the current working directory of the current drive. 85 | 86 | Equal to: getdcwd95(0,buf,buflen) 87 | */ 88 | 89 | /* Always use IO95 functions */ 90 | #ifdef USE_IO95 91 | #define MAXNAME MAXNAME95 92 | #define MAXPATH MAXPATH95 93 | #define dirent dirent95 94 | #define DIR DIR95 95 | #define opendir opendir95 96 | #define readdir readdir95 97 | #define telldir telldir95 98 | #define seekdir seekdir95 99 | #define closedir closedir95 100 | #define rewinddir rewinddir95 101 | #endif 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /IO95/ERRLIST: -------------------------------------------------------------------------------- 1 | Borland C++ 5.2 Copyright (c) 1987, 1997 Borland International 2 | Mar 19 1997 17:29:40 3 | find95.c: 4 | Warning find95.c 100: Call to function 'findfile' with no prototype in function findfirst 5 | Warning find95.c 109: Call to function 'findfile' with no prototype in function findnext 6 | fllpth95.c: 7 | getcwd95.c: 8 | l2s95.c: 9 | mkdir95.c: 10 | open95.c: 11 | ren95.c: 12 | win95api.c: 13 | dir95.c: 14 | fopen95.c: 15 | -------------------------------------------------------------------------------- /IO95/FILES: -------------------------------------------------------------------------------- 1 | *.C Source code files of IO95 library 2 | DIR95.H Declarations for POSIX.1 opendir() & assoc. 3 | FIND95.H Declarations for DOS semistandard findfirst() & assoc. 4 | STDIO95.H Declarations for functions 5 | IO95.H Declarations for other Win9x LFN API functions 6 | T.CC Test program 7 | errlist Errors generated by BCC v5.2 (2 Warnings) 8 | mklib.bat Sample script how to generate the library (in subdirs) 9 | mktest.bat Sample script how to generate the test program (in subdirs) 10 | tst.bat Sample script how to invoke the test program 11 | tst.out Should-be output of test program 12 | history Change-log / history of IO95 library 13 | copying.* GLPL and GPL -- the licenses this library is copyrighted under 14 | -------------------------------------------------------------------------------- /IO95/FIND95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: FIND95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | findfirst/findnext loop 5 | 6 | == For instance: 7 | struct ffblk95 ff; 8 | 9 | if(findfirst95("some_path\\wildcard_pattern", &ff, file_attribs) == 0) do { 10 | printf("SFN = %s\n", ff.ff_95.ff_shortname); 11 | printf("LFN = %s\n", ff.ff_95.ff_longname); 12 | } while(findnext95(&ff)); 13 | == 14 | 15 | == Example #2: 16 | int access95(const char fnam[], int mode) 17 | { struct ffblk95 ff; 18 | // Design flaw: Wildcards are accepted :-( 19 | 20 | if(findfirst95(fnam, &ff, FA95_HIDDEN | FA95_SYSTEM)) 21 | return -1; // error 22 | 23 | findstop95(&ff); // MUST BE CALLED for Win95 LFN! 24 | 25 | switch(mode) { 26 | case 0: // file exists 27 | case 1: // Execute permission -- ignored 28 | case 4: // Read permission 29 | break; 30 | case 2: // write permission 31 | case 6: // r&w permission 32 | if((ff.ff_attr & FA95_RDONLY) == 0) 33 | break; 34 | default: 35 | return -1; // error 36 | } 37 | 38 | return 0; 39 | } 40 | == 41 | 42 | $Log: not supported by cvs2svn $ 43 | Revision 1.2 2000/01/11 09:34:27 ska 44 | add: support Turbo C v2.01 45 | 46 | Revision 1.1 2000/01/11 09:10:08 ska 47 | Auto Check-in 48 | 49 | */ 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include "io95.h" 57 | #include "find95.h" 58 | 59 | #ifdef findfirst 60 | #undef findfirst 61 | #undef findnext 62 | #endif 63 | 64 | #define FIND_FIRST 0x4e00 65 | #define FIND_NEXT 0x4f00 66 | 67 | #ifndef lint 68 | static char const rcsid[] = 69 | "$Id: FIND95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 70 | #endif 71 | 72 | #ifndef HAVE_GETSETDTA 73 | void setdta(char far *dta) 74 | { struct REGPACK rp; 75 | 76 | assert(dta); 77 | rp.r_ds = FP_SEG(dta); 78 | rp.r_dx = FP_OFF(dta); 79 | rp.r_ax = 0x1a00; 80 | intr(0x21, &rp); 81 | } 82 | char far *getdta(void) 83 | { struct REGPACK rp; 84 | 85 | rp.r_ax = 0x2f00; 86 | intr(0x21, &rp); 87 | 88 | return MK_FP(rp.r_es, rp.r_bx); 89 | } 90 | #endif 91 | 92 | 93 | static int findfile(); 94 | 95 | /* Start a search and fill the FF block 96 | Return: 97 | == 0: OK 98 | != 0: failure; OS error code 99 | */ 100 | int findfirst(char *name, FF_Block95 *ff, int attr) 101 | /**Warning: Call to function 'findfile' with no prototype */ 102 | { return findfile(ff, FIND_FIRST, name, attr); 103 | } 104 | 105 | /* Continue a previously startet search. 106 | Return: 107 | s. findfirst 108 | */ 109 | int findnext(FF_Block95 *ff) 110 | /**Warning: Call to function 'findfile' with no prototype */ 111 | { return findfile(ff, FIND_NEXT); 112 | } 113 | 114 | 115 | /* Convert DOS style FF_Block95 into Win95 style */ 116 | static void convDOS(FF_Block95 *ff) 117 | { 118 | memcpy(ff->ff_95.ff_shortname, ff->ff_name, sizeof(ff->ff_name)); 119 | memcpy(ff->ff_95.ff_longname, ff->ff_name, sizeof(ff->ff_name)); 120 | ff->ff_95.ff_attr95 = ff->ff_attr; 121 | ff->ff_95.ff_losize = ff->ff_size; 122 | ff->ff_95.ff_hisize = 0; 123 | } 124 | 125 | 126 | /* 127 | * Find first/next file 128 | * Return: OS error code 129 | */ 130 | static int findfile(FF_Block95 *ff, int mode, char *name, int attr) 131 | { struct REGPACK rp; 132 | char far *curDTA; 133 | 134 | /* first swap the DTA */ 135 | curDTA = getdta(); 136 | assert(curDTA); 137 | setdta((char far*)ff); 138 | 139 | /* second peform the desired command */ 140 | if((rp.r_ax = mode) == FIND_FIRST) { 141 | rp.r_ds = FP_SEG(name); 142 | rp.r_dx = FP_OFF(name); 143 | rp.r_cx = attr; 144 | } 145 | intr(0x21, &rp); 146 | 147 | /* third re-set previous DTA */ 148 | setdta(curDTA); 149 | 150 | convDOS(ff); 151 | 152 | /* forth check for an error */ 153 | return (rp.r_flags & 1)? errno = rp.r_ax: 0; 154 | } 155 | 156 | /* Convert win95 style FF_Block95 into DOS style */ 157 | static void conv95(FF_Block95 *ff) 158 | { if(!*ff->ff_95.ff_shortname) 159 | memcpy(ff->ff_95.ff_shortname, ff->ff_95.ff_longname 160 | , sizeof(ff->ff_95.ff_shortname)); 161 | memcpy(ff->ff_name, ff->ff_95.ff_shortname, sizeof(ff->ff_name)); 162 | ff->ff_attr = (unsigned char)ff->ff_95.ff_attr95; 163 | ff->ff_size = ff->ff_95.ff_losize; 164 | } 165 | 166 | 167 | static int find95(char *name, FF_Block95 *ff, int attr) 168 | { struct REGPACK r; 169 | 170 | r.r_ax = 0x714e; 171 | r.r_cx = attr; 172 | r.r_si = 1; /* MS-DOS style time */ 173 | r.r_ds = FP_SEG(name); 174 | r.r_dx = FP_OFF(name); 175 | r.r_es = FP_SEG(&ff->ff_95); 176 | r.r_di = FP_OFF(&ff->ff_95); 177 | r.r_flags = 0; 178 | intr(0x21, &r); 179 | if(r.r_flags & 1) { /* Failure */ 180 | ff->ff_95.ff_status = NOFIND95; 181 | return r.r_ax; 182 | } 183 | ff->ff_95.ff_status = r.r_ax; 184 | conv95(ff); 185 | return 0; /* OK */ 186 | } 187 | 188 | static int next95(FF_Block95 *ff) 189 | { struct REGPACK r; 190 | 191 | r.r_ax = 0x714f; 192 | r.r_bx = ff->ff_95.ff_status; 193 | r.r_si = 1; /* MS-DOS style time/date */ 194 | r.r_es = FP_SEG(&ff->ff_95); 195 | r.r_di = FP_OFF(&ff->ff_95); 196 | r.r_flags = 0; 197 | intr(0x21, &r); 198 | if(r.r_flags & 1) 199 | return r.r_ax; 200 | conv95(ff); 201 | return 0; 202 | } 203 | 204 | int findfirst95(char *name, FF_Block95 *ff, int attr) 205 | { int err; 206 | 207 | assert(name); 208 | assert(ff); 209 | if(find95(name, ff, attr & 0x7f) == 0) 210 | return 0; /* OK */ 211 | return findfirst(name, ff, attr); 212 | } 213 | int findnext95(FF_Block95 *ff) 214 | { assert(ff); 215 | return ff->ff_95.ff_status == NOFIND95? findnext(ff): next95(ff); 216 | } 217 | void findstop95(FF_Block95 *ff) 218 | { assert(ff); 219 | if(ff->ff_95.ff_status != NOFIND95) { 220 | struct REGPACK r; 221 | 222 | r.r_ax = 0x71a1; 223 | r.r_bx = ff->ff_95.ff_status; 224 | intr(0x21, &r); 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /IO95/FIND95.H: -------------------------------------------------------------------------------- 1 | /* $Id: FIND95.H,v 1.1 2006-07-04 19:07:58 perditionc Exp $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | 5 | $Log: not supported by cvs2svn $ 6 | Revision 1.1 2000/01/11 09:10:09 ska 7 | Auto Check-in 8 | 9 | */ 10 | 11 | #ifndef __DOSFIND_H 12 | #define __DOSFIND_H 13 | 14 | #define DTALEN 128 15 | #define NOFIND95 0 16 | 17 | typedef unsigned char QWORD[8]; 18 | 19 | #define FA95_RDONLY 1 20 | #define FA95_HIDDEN 2 21 | #define FA95_SYSTEM 4 22 | #define FA95_LABEL 8 23 | #define FA95_VOLUME FA95_LABEL 24 | #define FA95_DIREC 16 25 | #define FA95_ARCHIVE 32 26 | #define FA95_ARCH FA95_ARCHIVE 27 | #define FA95_ALL 0x3f 28 | 29 | 30 | typedef struct ffblk95 { 31 | char ff_fcb[0x15]; 32 | unsigned char ff_attr; 33 | #define ff_attrib ff_attr 34 | unsigned short ff_time; 35 | #define ff_ftime ff_time 36 | unsigned short ff_date; 37 | #define ff_fdate ff_date 38 | long ff_size; 39 | #define ff_fsize ff_size 40 | char ff_name[14]; 41 | /* block for Win95 */ 42 | struct { 43 | long ff_attr95; 44 | long ff_creattime; 45 | long ff_creatdate; 46 | long ff_accesstime; 47 | long ff_accessdate; 48 | long ff_modtime; 49 | long ff_moddate; 50 | long ff_hisize; 51 | long ff_losize; 52 | char ff_dummy[8]; 53 | char ff_longname[260]; 54 | char ff_shortname[14]; 55 | unsigned ff_status; 56 | } ff_95; 57 | } FF_Block95; 58 | 59 | #ifndef HAVE_GETSETDTA 60 | /* Providing access to the process's DTA 61 | */ 62 | extern char far *getdta (void); 63 | extern void setdta (char far*); 64 | #endif 65 | 66 | int findfirst95(char *, FF_Block95 *, int); 67 | /* Start a search and fill the FF block 68 | 69 | If ff_95.ff_status != NOFIND95, the values of ff_95 are invalid. 70 | The "normal" values are always correct. 71 | 72 | Return: 73 | == 0: OK 74 | != 0: failure; OS error code 75 | */ 76 | 77 | int findnext95(FF_Block95 *); 78 | /* Continue a previously startet search. 79 | Return: 80 | s. findfirst 81 | */ 82 | 83 | void findstop95(FF_Block95 *); 84 | /* This function must be called, if the findfirst95/findnext95 loop 85 | shall be terminated before findfirst95() or findnext95() have 86 | returned with failure. 87 | */ 88 | 89 | #ifdef USE_IO95 90 | #undef findfirst 91 | #undef findnext 92 | #undef findstop 93 | #undef FF_Block 94 | #undef ffblk 95 | #undef FA_RDONLY 96 | #undef FA_HIDDEN 97 | #undef FA_SYSTEM 98 | #undef FA_LABEL 99 | #undef FA_VOLUME 100 | #undef FA_DIREC 101 | #undef FA_ARCHIVE 102 | #undef FA_ARCH 103 | #define findfirst findfirst95 104 | #define findnext findnext95 105 | #define findstop findstop95 106 | #define FF_Block FF_Block95 107 | #define ffblk ffblk95 108 | #define FA_RDONLY FA95_RDONLY 109 | #define FA_HIDDEN FA95_HIDDEN 110 | #define FA_SYSTEM FA95_SYSTEM 111 | #define FA_LABEL FA95_LABEL 112 | #define FA_VOLUME FA95_VOLUME 113 | #define FA_DIREC FA95_DIREC 114 | #define FA_ARCHIVE FA95_ARCHIVE 115 | #define FA_ARCH FA95_ARCH 116 | #define FA_ALL FA95_ALL 117 | #endif 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /IO95/FLLPTH95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: FLLPTH95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | char *fullpath(char *buffer, char *path, int buflen) 5 | 6 | Fully-qualify path. 7 | If buffer != NULL, buflen tells its size. 8 | If buffer == NULL, a buffer of buflen bytes is malloc'ed. 9 | 10 | This code requires to define "maximum" values for the filesystem: 11 | MAXPATH95 260 12 | MAXNAME95 255 13 | Unfortunately, these values are assumptions for Win95 & DOS only! 14 | 15 | If the path starts with "\\\\" both backslashes remain; that 16 | gives some support for UNC path spec. 17 | 18 | $Log: not supported by cvs2svn $ 19 | Revision 1.2 2000/01/11 09:34:30 ska 20 | add: support Turbo C v2.01 21 | 22 | Revision 1.1 2000/01/11 09:10:08 ska 23 | Auto Check-in 24 | 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "io95.h" 35 | 36 | #define MAXDRVLEN 2 37 | 38 | #ifndef lint 39 | static char const rcsid[] = 40 | "$Id: FLLPTH95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 41 | #endif 42 | 43 | 44 | /* 45 | * fullpath 46 | */ 47 | 48 | char *fullpath95(char * const Xbuffer, const char *path, int Xbuflen) 49 | { 50 | int drive, buflen; 51 | char *p; /* points to place, where to start a new path component */ 52 | char *buffer; /* buffer to be work over */ 53 | char *lowbound; /* boundary never to undergo */ 54 | const char *pp; 55 | 56 | assert(path); 57 | 58 | if((buflen = Xbuflen) <= 0) 59 | buflen = MAXPATH95; 60 | if((buffer = Xbuffer) == NULL && (buffer = malloc(buflen)) == NULL) 61 | return NULL; 62 | 63 | if(*path == '\\' && path[1] == '\\') { /* assume an UNC path */ 64 | /* two shares must be present! */ 65 | if(*(pp = &path[2]) == '\\' || *pp == '/') 66 | goto errRet; 67 | while(*pp && *pp != '\\' && *pp != '/') ++pp; 68 | if(!*pp) goto errRet; /* at least two shares */ 69 | while(*pp && *pp != '\\' && *pp != '/') ++pp; 70 | if(buflen <= (drive = pp - path)) 71 | goto errRet; 72 | memcpy(buffer, path, drive); 73 | path = pp; 74 | lowbound = p = buffer + drive; 75 | } 76 | else { 77 | lowbound = buffer + 2; 78 | if(path[1] == ':') { 79 | if(!isalpha(*path)) 80 | goto errRet; /* invalid file spec */ 81 | drive = toupper(path[0]) - 'A'; 82 | path += 2; 83 | } 84 | else 85 | drive = getdisk(); /* current drive */ 86 | 87 | if(*path == '\\' || *path == '/') { 88 | /* fully-qualified path needn't getcwd */ 89 | *buffer = drive + 'A'; 90 | buffer[1] = ':'; 91 | *(p = &buffer[2]) = '\0'; 92 | } 93 | else if(!getdcwd95(drive + 1, buffer, buflen)) /* get working directory failed */ 94 | goto errRet; 95 | else if((p = strchr(buffer, '\0'))[-1] == '\\') 96 | --p; 97 | } 98 | 99 | /* 100 | Now copy all remaining components from path to buffer 101 | */ 102 | 103 | do { 104 | /* first chop path delimiter characters */ 105 | while(*path == '/' || *path == '\\') ++path; 106 | /* second break, if path has been used up */ 107 | if(!*path) break; 108 | /* third identify '.' and '..' */ 109 | if(*path == '.') switch(path[1]) { 110 | case '/': case '\\': case '\0': 111 | ++path; /* skip '.' */ 112 | continue; 113 | case '.': /* probably: '..' */ 114 | switch(path[2]) { 115 | case '/': case '\\': case '\0': 116 | path += 2; /* skip '..' */ 117 | /* chop last path component */ 118 | while(--p > lowbound && *p != '/' && *p != '\\'); 119 | continue; 120 | } 121 | break; 122 | } 123 | /* forth copy this path component */ 124 | *p++ = '\\'; 125 | while(*path && *path != '/' && *path != '\\') 126 | if(p >= buffer + buflen) 127 | goto errRet; /* buffer overflow */ 128 | else *p++ = *path++; 129 | } while(1); 130 | 131 | if(p == lowbound) /* root drive */ 132 | *p++ = '\\'; 133 | *p = '\0'; 134 | 135 | if(!Xbuffer && Xbuflen <= 0 136 | && (p = realloc(buffer, strlen(buffer) + 1)) != NULL) 137 | return p; 138 | 139 | return buffer; 140 | 141 | errRet: 142 | if(!Xbuffer) 143 | free(buffer); 144 | 145 | return NULL; 146 | } 147 | -------------------------------------------------------------------------------- /IO95/FOPEN95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: FOPEN95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | FILE *fopen(const char fnam[], const char mode[]) 5 | 6 | Open the file "fnam" in the mode "mode" supporting LFN of Win95. 7 | If Win95 is not running, DOS 4 functionality is used. 8 | 9 | Mode supports: r, w, a, +, t,& b 10 | 11 | Note: This function does NOT support DOS prior version 4! 12 | 13 | $Log: not supported by cvs2svn $ 14 | Revision 1.2 2000/01/11 09:39:33 ska 15 | add: STDIO95.H 16 | 17 | Revision 1.1 2000/01/11 09:10:09 ska 18 | Auto Check-in 19 | 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #ifndef HAVE_FDOPEN 26 | #include 27 | #endif 28 | 29 | #ifdef USE_IO95 30 | #undef USE_IO95 31 | #endif 32 | #include "stdio95.h" 33 | 34 | #ifndef HAVE_FDOPEN 35 | FILE *fdopen(int fd, const char mode[]) 36 | { FILE *f; 37 | 38 | if((f = fopen("NUL", mode)) == NULL) 39 | return NULL; 40 | 41 | if(dup2(fd, fileno(f)) == 0) 42 | return f; 43 | 44 | fclose(f); 45 | return NULL; 46 | } 47 | #undef HAVE_FDOPEN 48 | #define HAVE_FDOPEN fdopen 49 | #endif 50 | 51 | FILE *fopen95(const char fnam[], const char mode[]) 52 | { FILE *h; 53 | int fd; 54 | int omode, amode; 55 | const char *p; 56 | 57 | assert(fnam); 58 | assert(mode); 59 | 60 | if((p = strpbrk(mode, "rwa")) == NULL) 61 | return NULL; /* no open mode */ 62 | 63 | switch(*p) { 64 | case 'r': amode = O95_RDONLY; omode = 0; break; 65 | case 'w': amode = O95_WRONLY; omode = O95_CREAT | O95_TRUNC; break; 66 | default: amode = O95_WRONLY; omode = O95_CREAT | O95_APPEND; break; 67 | } 68 | 69 | omode |= strchr(mode, '+')? O95_RDWR: amode; 70 | 71 | if((p = strpbrk(mode, "tb")) != NULL) 72 | omode |= *p == 't'? O95_TEXT: O95_BINARY; 73 | 74 | if((fd = open95(fnam, omode, S95_IREAD | S95_IWRITE)) == -1) 75 | return NULL; 76 | 77 | h = HAVE_FDOPEN(fd, (char*)mode); 78 | if(!h) 79 | close(fd); 80 | 81 | return h; 82 | } 83 | -------------------------------------------------------------------------------- /IO95/GETCWD95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: GETCWD95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | getdcwd/getcwd/getcurrdir 5 | 6 | This code requires to define "maximum" values for the filesystem: 7 | MAXPATH95 260 8 | MAXNAME95 255 9 | Unfortunately, these values are assumptions for Win95 & DOS only! 10 | 11 | $Log: not supported by cvs2svn $ 12 | Revision 1.2 2000/01/11 09:34:33 ska 13 | add: support Turbo C v2.01 14 | 15 | Revision 1.1 2000/01/11 09:10:09 ska 16 | Auto Check-in 17 | 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #ifdef USE_IO95 28 | #undef USE_IO95 29 | #endif 30 | 31 | #include "dir95.h" 32 | #include "io95.h" 33 | #include "io95_loc.h" 34 | 35 | #ifndef lint 36 | static char const rcsid[] = 37 | "$Id: GETCWD95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 38 | #endif 39 | 40 | 41 | /* 42 | Get current working directory without drive/colon/leading backslash 43 | 44 | Return: 45 | 0: success 46 | -1: error 47 | */ 48 | int getcurdir95(int drive, char * const dir) 49 | { struct REGPACK rp; 50 | 51 | assert(dir); 52 | rp.r_ax = 0x7147; 53 | rp.r_si = FP_OFF(dir); 54 | rp.r_ds = FP_SEG(dir); 55 | rp.r_dx = drive; 56 | 57 | if(callWin95(0x47, &rp)) { 58 | errno = rp.r_ax; 59 | return -1; 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | char * getdcwd95(int drive, char *buf, int buflen) 66 | { 67 | char hbuf[MAXPATH95 * 2]; 68 | 69 | if(getcurdir95(drive, hbuf)) 70 | return NULL; 71 | 72 | /* Construct the fully-qualified path */ 73 | if(!buflen) 74 | buflen = strlen(hbuf) + 1; 75 | else if(buflen < strlen(hbuf) + 4) { 76 | errno = ERANGE; 77 | return NULL; 78 | } 79 | if(!buf && (buf = malloc(buflen)) == NULL) 80 | return NULL; 81 | if((*buf = 'A' - 1 + drive) == 'A' - 1) 82 | *buf = 'A' + getdisk(); 83 | buf[1] = ':'; 84 | 85 | if(*hbuf == '\\') 86 | strcpy(&buf[2], hbuf); 87 | else { 88 | buf[2] = '\\'; 89 | strcpy(&buf[3], hbuf); 90 | } 91 | 92 | return buf; 93 | } 94 | 95 | char * getcwd95(char *buf, int buflen) 96 | { return getdcwd95(0, buf, buflen); } 97 | -------------------------------------------------------------------------------- /IO95/HISTORY: -------------------------------------------------------------------------------- 1 | Release version IO95 v1 2 | 3 | add: STDIO95.H 4 | add: support Turbo C v2.01 5 | 6 | Initial revision 7 | -------------------------------------------------------------------------------- /IO95/IO95.H: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/IO95/IO95.H -------------------------------------------------------------------------------- /IO95/IO95_LOC.H: -------------------------------------------------------------------------------- 1 | /* $Id: IO95_LOC.H,v 1.1 2006-07-04 19:07:58 perditionc Exp $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | Local functions of the IO95 library 5 | 6 | $Log: not supported by cvs2svn $ 7 | Revision 1.1 2000/01/11 09:34:51 ska 8 | Initial revision 9 | 10 | */ 11 | 12 | #ifndef __IO95_LOC_H 13 | #define __IO95_LOC_H 14 | 15 | int callWin95(int fct, struct REGPACK * const rp); 16 | /* Invoke Win95/DOS function fct. It assumes that both APIs are the 17 | same except for the function number itself. 18 | 19 | *rp will hold the values of the successful call (either Win95 20 | or DOS). 21 | 22 | Return: 23 | 0: success 24 | else: failure 25 | */ 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /IO95/L2S95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: L2S95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | int lfn2sfn95(const char * const fnam, char * const buf); 5 | 6 | fully-qualify fnam and convert all long filename portions into 7 | their short form. 8 | 9 | Return: 10 | 0: success 11 | 2: invalid component in path or drive letter 12 | 3: malformed path or buffer too short 13 | 14 | 15 | $Log: not supported by cvs2svn $ 16 | Revision 1.1 2000/01/11 09:10:09 ska 17 | Auto Check-in 18 | 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include "io95.h" 25 | 26 | #ifndef lint 27 | static char const rcsid[] = 28 | "$Id: L2S95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 29 | #endif 30 | 31 | static int conv95(int fct, const char * const fnam, char * const buf) 32 | { struct REGPACK r; 33 | 34 | assert(fnam); 35 | assert(buf); 36 | r.r_ax = 0x7160; 37 | r.r_cx = 0x8000 | fct; 38 | r.r_ds = FP_SEG(fnam); 39 | r.r_si = FP_OFF(fnam); 40 | r.r_es = FP_SEG(buf); 41 | r.r_di = FP_OFF(buf); 42 | r.r_flags = 0; 43 | *buf = '\0'; 44 | intr(0x21, &r); 45 | if(r.r_flags & 1) { 46 | if(*buf && r.r_ax == 3 && strlen(buf) > 255) 47 | /* assume the bug */ 48 | return 0; 49 | return r.r_ax; 50 | } 51 | return 0; 52 | } 53 | 54 | int truename95(const char * const fnam, char * const buf) 55 | { return conv95(2, fnam, buf); } 56 | int lfn2sfn95(const char * const fnam, char * const buf) 57 | { return conv95(1, fnam, buf); } 58 | -------------------------------------------------------------------------------- /IO95/MAKEFILE: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for io95 by Steffen Kaiser 3 | # 4 | 5 | compiler = tcc -c 6 | linker = tcc 7 | lib = tlib 8 | 9 | options = -v -y -vi # from the mklib.bat file 10 | 11 | objects = ren95.obj mkdir95.obj l2s95.obj win95api.obj fopen95.obj \ 12 | getcwd95.obj dir95.obj fllpth95.obj find95.obj open95.obj \ 13 | dir95.obj 14 | 15 | all: $(objects) 16 | @..\delete io95.lib 17 | @$(lib) io95 + ren95.obj 18 | @$(lib) io95 + mkdir95.obj 19 | @$(lib) io95 + l2s95.obj 20 | @$(lib) io95 + win95api.obj 21 | @$(lib) io95 + fopen95.obj 22 | @$(lib) io95 + getcwd95.obj 23 | @$(lib) io95 + dir95.obj 24 | @$(lib) io95 + fllpth95.obj 25 | @$(lib) io95 + find95.obj 26 | @$(lib) io95 + open95.obj 27 | 28 | ren95.obj: ren95.c 29 | @$(compiler) $(options) ren95.c 30 | 31 | mkdir95.obj: mkdir95.c 32 | @$(compiler) $(options) mkdir95.c 33 | 34 | l2s95.obj: l2s95.c 35 | @$(compiler) $(options) l2s95.c 36 | 37 | win95api.obj: win95api.c 38 | @$(compiler) $(options) win95api.c 39 | 40 | fopen95.obj: fopen95.c 41 | @$(compiler) $(options) fopen95.c 42 | 43 | getcwd95.obj: getcwd95.c 44 | @$(compiler) $(options) getcwd95.c 45 | 46 | dir95.obj: dir95.c 47 | @$(compiler) $(options) dir95.c 48 | 49 | fllpth95.obj: fllpth95.c 50 | @$(compiler) $(options) fllpth95.c 51 | 52 | find95.obj: find95.c 53 | @$(compiler) $(options) find95.c 54 | 55 | open95.obj: open95.c 56 | @$(compiler) $(options) open95.c 57 | 58 | clean: 59 | @..\delete ren95.obj 60 | @..\delete mkdir95.obj 61 | @..\delete l2s95.obj 62 | @..\delete win95api.obj 63 | @..\delete fopen95.obj 64 | @..\delete getcwd95.obj 65 | @..\delete dir95.obj 66 | @..\delete fllpth95.obj 67 | @..\delete find95.obj 68 | @..\delete open95.obj 69 | @..\delete io95.lib 70 | -------------------------------------------------------------------------------- /IO95/MKDIR95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: MKDIR95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | int mkdir95(char *dnam); 5 | int rmdir95(char *dnam); 6 | int chdir95(char *dnam); 7 | 8 | Make/Remove/Change directory supporting Win95 LFN. 9 | 10 | Return: 11 | 0: success 12 | else: failure 13 | 14 | $Log: not supported by cvs2svn $ 15 | Revision 1.2 2000/01/11 09:34:36 ska 16 | add: support Turbo C v2.01 17 | 18 | Revision 1.1 2000/01/11 09:10:09 ska 19 | Auto Check-in 20 | 21 | */ 22 | 23 | #include 24 | #include 25 | #include "io95.h" 26 | #include "io95_loc.h" 27 | 28 | #ifndef lint 29 | static char const rcsid[] = 30 | "$Id: MKDIR95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 31 | #endif 32 | 33 | static int callAPI(int fct, const char * const dnam) 34 | { struct REGPACK r; 35 | 36 | assert(dnam); 37 | r.r_ds = FP_SEG(dnam); 38 | r.r_dx = FP_OFF(dnam); 39 | return callWin95(fct, &r); 40 | } 41 | 42 | int mkdir95(const char * const dnam) 43 | { 44 | return callAPI(0x39, dnam); 45 | } 46 | 47 | int rmdir95(const char * const dnam) 48 | { 49 | return callAPI(0x3a, dnam); 50 | } 51 | 52 | int chdir95(const char * const dnam) 53 | { 54 | return callAPI(0x3b, dnam); 55 | } 56 | -------------------------------------------------------------------------------- /IO95/OPEN95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: OPEN95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | int open95(char *fnam, long omode [, int flags] ) 5 | 6 | Open the file "fname" in the mode "omode" supporting LFN of Win95. 7 | If Win95 is not running, DOS 4 functionality is used. 8 | 9 | Note: This function does NOT support DOS prior version 4! 10 | 11 | $Log: not supported by cvs2svn $ 12 | Revision 1.1 2000/01/11 09:10:09 ska 13 | Auto Check-in 14 | 15 | */ 16 | 17 | #include 18 | #include 19 | #include // REGPACK 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef USE_IO95 25 | #undef USE_IO95 26 | #endif 27 | #define IO95_NO_OPEN_PROTOTYPE 28 | #include "io95.h" 29 | 30 | #define OPEN_CREATE (1 << 4) 31 | #define OPEN_TRUNC (1 << 1) 32 | #define OPEN_OPEN (1 << 0) 33 | #define OPEN_FLAGS (O95_AUTOCOMMIT | O95_NOCRIT | O95_NOCOMPRESS | O95_UNBUFFERED | 0xff) 34 | #define OPEN_SHARE (7<<4) 35 | 36 | #ifndef lint 37 | static char const rcsid[] = 38 | "$Id: OPEN95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 39 | #endif 40 | 41 | 42 | /**************** API 43 | --------D-21716C----------------------------- 44 | INT 21 - Windows95 - LONG FILENAME - CREATE OR OPEN FILE 45 | AX = 716Ch 46 | BX = access mode and sharing flags (see #1122,also AX=6C00h) 47 | CX = attributes 48 | DX = action (see #1121) 49 | DS:SI -> ASCIZ filename 50 | DI = alias hint (number to append to short filename for disambiguation) 51 | Return: CF clear if successful 52 | AX = file handle 53 | CX = action taken 54 | 0001h file opened 55 | 0002h file created 56 | 0003h file replaced 57 | CF set on error 58 | AX = error code (see #1020) 59 | 7100h if function not supported 60 | SeeAlso: AX=6C00h,AX=7141h,AX=7156h,AX=71A9h 61 | 62 | Bitfields for Windows95 long-name open action: 63 | Bit(s) Description (Table 1121) 64 | 0 open file (fail if file does not exist) 65 | 1 truncate file if it already exists (fail if file does not exist) 66 | 4 create new file if file does not already exist (fail if exists) 67 | Note: the only valid combinations of multiple flags are bits 4&0 and 4&1 68 | 69 | Bitfields for Windows95 file access/sharing modes: 70 | Bit(s) Description (Table 1122) 71 | 2-0 file access mode 72 | 000 read-only 73 | 001 write-only 74 | 010 read-write 75 | 100 read-only, do not modify file's last-access time 76 | 6-4 file sharing modes 77 | 7 no-inherit flag 78 | 8 do not buffer data (requires that all reads/writes be exact physical 79 | sectors) 80 | 9 do not compress file even if volume normally compresses files 81 | 10 use alias hint in DI as numeric tail for short-name alias 82 | 12-11 unused??? (0) 83 | 13 return error code instead of generating INT 24h if critical error 84 | while opening file 85 | 14 commit file after every write operation 86 | SeeAlso: #0749 87 | 88 | 89 | --------D-216C00----------------------------- 90 | INT 21 - DOS 4.0+ - EXTENDED OPEN/CREATE 91 | AX = 6C00h 92 | BL = open mode as in AL for normal open (see also AH=3Dh) 93 | bit 7: inheritance 94 | bits 4-6: sharing mode 95 | bit 3 reserved 96 | bits 0-2: access mode 97 | 100 read-only, do not modify file's last-access time (DOS 7.0) 98 | BH = flags 99 | bit 6 = auto commit on every write (see also AH=68h) 100 | bit 5 = return error rather than doing INT 24h 101 | bit 4 = (FAT32) extended size (>= 2GB) 102 | CX = create attribute (see #1111) 103 | DL = action if file exists/does not exist (see #1112) 104 | DH = 00h (reserved) 105 | DS:SI -> ASCIZ file name 106 | Return: CF set on error 107 | AX = error code (see #1020 at AH=59h/BX=0000h) 108 | CF clear if successful 109 | AX = file handle 110 | CX = status (see #1110) 111 | Notes: the PC LAN Program only supports existence actions (in DL) of 01h, 112 | 10h with sharing=compatibility, and 12h 113 | DR DOS reportedly does not support this function and does not return 114 | an "invalid function call" error when this function is used. 115 | the documented bits of BX are stored in the SFT when the file is opened 116 | (see #0982,#0983) 117 | BUG: this function has bugs (at least in DOS 5.0 and 6.2) when used with 118 | drives handled via the network redirector (INT 2F/AX=112Eh): 119 | - CX (attribute) is not passed to the redirector if DL=11h, 120 | - CX does not return the status, it is returned unchanged because 121 | DOS does a PUSH CX/POP CX when calling the redirector. 122 | SeeAlso: AH=3Ch,AH=3Dh,AX=6C01h,AH=71h,INT 2F/AX=112Eh 123 | 124 | (Table 1110) 125 | Values for extended open function status: 126 | 01h file opened 127 | 02h file created 128 | 03h file replaced 129 | 130 | Bitfields for file create attribute: 131 | Bit(s) Description (Table 1111) 132 | 6-15 reserved 133 | 5 archive 134 | 4 reserved 135 | 3 volume label 136 | 2 system 137 | 1 hidden 138 | 0 readonly 139 | 140 | Bitfields for action: 141 | Bit(s) Description (Table 1112) 142 | 7-4 action if file does not exist 143 | 0000 fail 144 | 0001 create 145 | 3-0 action if file exists 146 | 0000 fail 147 | 0001 open 148 | 0010 replace/open 149 | **************/ 150 | 151 | int open95(const char * const fnam, long omode, int flags) 152 | { struct REGPACK r, r1; 153 | int h; 154 | 155 | assert(fnam); 156 | /* Frist try the Win95 API */ 157 | r.r_flags = 1; /* make sure the carru is set */ 158 | r.r_ds = FP_SEG(fnam); /* pointer to file name */ 159 | r.r_si = FP_OFF(fnam); 160 | r.r_ax = 0x716c; /* Win95 open/create */ 161 | r.r_cx = flags ^ S95_IWRITE; 162 | if(omode & O95_CREAT) /* creation behaviour */ 163 | r.r_dx = (omode & O95_EXCL)? OPEN_CREATE 164 | : (omode & O95_TRUNC)? OPEN_CREATE | OPEN_TRUNC 165 | : OPEN_CREATE | OPEN_OPEN; 166 | else 167 | r.r_dx = (omode & O95_TRUNC)? OPEN_TRUNC: OPEN_OPEN; 168 | r.r_bx = omode & OPEN_FLAGS; 169 | if(!(r.r_bx & OPEN_SHARE)) 170 | r.r_bx |= O95_DENYWRITE; 171 | 172 | /* because the call the DOS 4 style function is nearly the same 173 | the structure is preserved for the next try */ 174 | memcpy(&r1, &r, sizeof(r)); 175 | 176 | intr(0x21, &r); /* Perform the Win95 API call */ 177 | 178 | if((r.r_flags & 1) /* failed */ 179 | && r.r_ax == 1) { /* Win95 not present -> call DOS 4 API */ 180 | r1.r_ax = 0x6c00; 181 | /* Suppress Win95 specific flags */ 182 | r1.r_bx &= O95_AUTOCOMMIT | O95_NOCRIT | O95_NOINHERIT | OPEN_SHARE | 3; 183 | 184 | intr(0x21, &r1); /* Perform DOS 4 API call */ 185 | 186 | if(r1.r_flags & 1) { /* failed, too */ 187 | errno = r1.r_ax; /* preserve this error */ 188 | return -1; 189 | } 190 | 191 | r.r_ax = r1.r_ax; /* re-join both APIs */ 192 | } 193 | 194 | /* One of the API returned successfully -> do whatever is needed */ 195 | 196 | /* Now there is some problem with the O95_TEXT/O95_BINARY flags. 197 | Borland supports the one, but it is "internally" done, what means 198 | it has to be simulated somehow. */ 199 | 200 | /* Well, we open another file with the original function and 201 | patch our handle onto that one. */ 202 | if((h = open("nul", (omode & O95_TEXT? O_TEXT: O_BINARY) | (omode & 3))) == -1) { 203 | /* Oops, something went a bit wrong here -> bail out immediately */ 204 | close(r.r_ax); 205 | return -1; 206 | } 207 | /* Now, we duplicate our handle over the returned one; DOS duplicates 208 | all necessary flags etc, but because we bypass the C library, 209 | the internal structure remains OK */ 210 | r1.r_ax = 0x4600; /* duplicate file handle to other file handle */ 211 | r1.r_bx = r.r_ax; 212 | r1.r_cx = h; 213 | intr(0x21, &r1); 214 | if(r1.r_flags & 1) { /* should never arise */ 215 | close(h); 216 | close(r.r_ax); 217 | return -1; 218 | } 219 | close(r.r_ax); /* is not needed anylonger! */ 220 | 221 | if(omode & O95_APPEND) /* seek to EOF */ 222 | lseek(h, 0l, 1); 223 | 224 | return h; 225 | } 226 | -------------------------------------------------------------------------------- /IO95/README: -------------------------------------------------------------------------------- 1 | /**** 2 | IO95 v1 - Win9x LFN API wrappers (DOSbox only) 3 | Copyright (C) 2000 Steffen Kaiser (Steffen.Kaiser@fh-rhein-sieg.de) 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Library General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Library General Public License for more details. 14 | 15 | You should have received a copy of the GNU Library General Public 16 | License along with this library; if not, write to the Free 17 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | ****/ 19 | 20 | This library IO95 includes some wrappers for the Win9x LFN API for 21 | real-mode programs (DOSbox) at DOS-71. 22 | 23 | Included are functions for: 24 | - POSIX.1 compatible opendir() functions, 25 | - DOS semistandard findfirst(), 26 | - open() (from ), 27 | - fopen() (from ), 28 | - mk/rm/chdir(), 29 | - remove() and unlink(), 30 | - rename(), 31 | - getcwd(), getdcwd(), getcurdir(), 32 | - fullpath() [to return a path in all longname portions], & 33 | - lfn2sfn() [to return a path in all shortname portions]. 34 | 35 | The library also defines MAXPATH, MAXNAME, etc. and all macros 36 | necessary to call above functions, e.g. O_CREAT, FA_DIREC etc. 37 | 38 | Naming convention: 39 | Usually all symbols are named after their standard counterpart, but 40 | "95" is appended, e.g. "open()" becomes "open95()", "MAXPATH" becomes 41 | "MAXPATH95". The exception are macros with an underscore in them, they 42 | have the "95" before the underscore, e.g. "O_CREAT" becomes "O95_CREAT". 43 | 44 | When the macro USE_IO95 is defined prior including any of the IO95 45 | header files, macros are enabled to map the standard name into the 46 | IO95 name. 47 | 48 | opendir95(): 49 | Declarations are located within the "DIR95.H" file. 50 | The only information returned by readdir95() is the longname of the found 51 | directory entry. telldir95() and seekdir95() do not directly patch the 52 | search structure of DOS. 53 | 54 | findfirst95(): 55 | Declarations are located within the "FIND95.H" file. 56 | The ffblk95 structure contains the "normal" fields and all of the 57 | Win95-LFN fields (in ff_95). Both fields are synchronized as much 58 | as possible, e.g. when the LFN API succeeds, the "normal" fields 59 | are updated with the values of the LFN API; if the LFN API fails, 60 | their values are updated with the "normal" ones. 61 | 62 | The members ff_95.ff_shortname and ff_95.ff_longname are always 63 | filled with a valid filename, though, it could be the same. 64 | 65 | If a findfirst95()/findnext95() loop shall break before one of these 66 | functions fails, the function findstop95() _must_ be called in order 67 | to release the resources allocated for the search structure by Win. 68 | 69 | See IO95.H to enable or disable HAVE_GETSETDTA. 70 | 71 | 72 | open(): 73 | This function _must_ be called with values derived from the O95_* 74 | and S95_I* macros only. One cannot use the ones from the C compiler's 75 | standard header files ( and )! 76 | 77 | Though, if USE_IO95 is defined prior including "IO95.H", the 78 | mapper names are installed. 79 | 80 | fopen(): 81 | Declared in "STDIO95.H". 82 | This function requires a fdopen() function. See STDIO95.H to setup 83 | this function correctly. 84 | 85 | LFN vs. SFN 86 | Win95-LFN implementation is sort of miraculeous, because the 87 | association between the LFN and SFN of the same physical file is 88 | rather loose and can change any time; but the LFN is the primary 89 | filename. 90 | 91 | This problem means that one cannot safe the SFN and re-use it later, 92 | probably in another session of a program days later. Rather one 93 | must keep the LFN. 94 | 95 | Within a relatively short lifetime of a program the association could 96 | be assumed stable, because (after all) Win9x is not that multi-tasking. 97 | Otherwise, the Win95-LFN implementation would have failed much more 98 | in the past. 99 | 100 | Therefore I recommended to: 101 | 1) aquire a filename from the user or from the system as LFN (e.g. 102 | findfirst95() or readdir95()), 103 | 2) turn it into a SFN (e.g. vie lfn2sfn()), 104 | 3) now all compiler-supplied filename function should work OK, 105 | 4) when a filename is passed to the user or system the SFN is 106 | translated into a LFN. 107 | Doing so will remarkable simplify to port programs that does not 108 | really care about how the filename looks like, but only scans 109 | through a directory tree, opens files typed in by the user etc. 110 | 111 | Also remember that a standard Win95-LFN has a different maximimum 112 | size: MAXPATH94 for the overall pathname, and MAXNAME95 for one 113 | individual path component. However, the Win95-LFN API does contain 114 | a function to retrieve the maximum pathname limits, though, the 115 | internal API does not seem to even assume that other than the 116 | standard settings are in effect ever; kind of normal MS API 117 | definition. 118 | 119 | Limits of this library: 120 | IO95 depends on the Win95-LFN API at DOS-71. So far only the DOSbox 121 | of Win9x supports this API, neither WinNT nor plain DOS without the 122 | GUI do. When and if WinNT or DOS (DR DOS has released a TSR for 123 | this, I've heard; but never seen) will be supported some day, I 124 | don't know. 125 | -------------------------------------------------------------------------------- /IO95/REN95.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: REN95.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | Rename file 5 | 6 | $Log: not supported by cvs2svn $ 7 | Revision 1.2 2000/01/11 09:34:39 ska 8 | add: support Turbo C v2.01 9 | 10 | Revision 1.1 2000/01/11 09:10:09 ska 11 | Auto Check-in 12 | 13 | */ 14 | 15 | #include 16 | #include 17 | #include "io95.h" 18 | #include "io95_loc.h" 19 | 20 | #ifndef lint 21 | static char const rcsid[] = 22 | "$Id: REN95.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 23 | #endif 24 | 25 | int rename95(const char * const oldnam, const char * const newnam) 26 | { struct REGPACK r; 27 | 28 | assert(oldnam); 29 | assert(newnam); 30 | r.r_ds = FP_SEG(oldnam); 31 | r.r_dx = FP_OFF(oldnam); 32 | r.r_es = FP_SEG(newnam); 33 | r.r_di = FP_OFF(newnam); 34 | r.r_si = 0; 35 | r.r_cx = 0; 36 | return callWin95(0x56, &r); 37 | } 38 | -------------------------------------------------------------------------------- /IO95/STDIO95.H: -------------------------------------------------------------------------------- 1 | /* $Id: STDIO95.H,v 1.1 2006-07-04 19:07:58 perditionc Exp $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | stdio functions supporting Win95's LFN as well as DOS 4+. 5 | 6 | $Log: not supported by cvs2svn $ 7 | Revision 1.1 2000/01/11 09:39:37 ska 8 | Initial revision 9 | 10 | */ 11 | 12 | #ifndef __STDIO95_H 13 | #define __STDIO95_H 14 | 15 | /****** 16 | compiler - specific settings 17 | *******/ 18 | 19 | /* Name of fdopen() if available */ 20 | #define HAVE_FDOPEN fdopen 21 | 22 | 23 | 24 | #include 25 | #include "io95.h" 26 | 27 | 28 | FILE *fopen95(const char fnam[], const char mode[]); 29 | 30 | 31 | /********** Define USE_IO95 to always use io95-functions ********/ 32 | #ifdef USE_IO95 33 | #undef fopen 34 | #define fopen fopen95 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /IO95/T.CC: -------------------------------------------------------------------------------- 1 | /* 2 | test IO95 lib 3 | 4 | prerequisites: 5 | 1) file "longfilename1" must exist 6 | 1) file "longfilename2" must not exist 7 | 3) subdir "longpathname" must not exist 8 | 9 | What is done: 10 | 1) "longfilename1" is opened 11 | 2) "longfilename2" is created 12 | 3) "longpathname\longerpath" is created 13 | 4) SFN("longpathname\longerpath") is displayed 14 | 5) chdir("longpathname\longerpath") 15 | 6) Display fullpath(.) 16 | 7) move longfilename2 into "." 17 | 8) display ".", "..", "longfilenameX" 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #define USE_IO95 24 | #include "io95.h" 25 | #include "find95.h" 26 | #include "dir95.h" 27 | 28 | main(void) 29 | { int fd, i, chdOK; 30 | char buf[2048]; 31 | struct ffblk ff; 32 | DIR *dirp; 33 | struct dirent95 *dep; 34 | long cnt; 35 | 36 | fd = open("longfilename1", O_SNOOP | O_TEXT); 37 | if(fd == -1) 38 | puts("Failed to open filename1"); 39 | else close(fd); 40 | 41 | fd = open("longfilename2", O_CREAT | O_TRUNC | O_TEXT | O_RDWR, S_IREAD | S_IWRITE); 42 | if(fd == -1) 43 | puts("Failed to create filename2"); 44 | else { 45 | for(i = 0; ++i < 1000;) { 46 | sprintf(buf, "line %d\n", i); 47 | write(fd, buf, strlen(buf)); 48 | } 49 | close(fd); 50 | } 51 | 52 | if(mkdir("longpathname")) 53 | puts("Cannot create longpathname"); 54 | else if(mkdir("longpathname\\longerpath")) 55 | puts("Cannot create longerpath"); 56 | if(lfn2sfn("longpathname\\longerpath", buf)) 57 | puts("Failed to get SFN(longpathname\\longerpath)"); 58 | else printf("SFN(longpathname\\longerpath) = \"%s\"\n", buf); 59 | if(chdir("longpathname\\longerpath")) { 60 | puts("chdir(longpathname\\longerpath) failed"); 61 | chdOK = 0; 62 | } 63 | else chdOK = 1; 64 | if(fullpath(buf, ".", sizeof(buf)) == NULL) 65 | puts("fullpath(.) failed"); 66 | else printf("Current fullpath = \"%s\"\n", buf); 67 | 68 | if(rename("..\\..\\longfilename2", "longfilenameX")) 69 | puts("Failed to move longfilename here"); 70 | 71 | puts("Entries found with findfirst/next loop:"); 72 | printf("%14s|%14s|%8s|%8s|%8s|%16s|%s\n", "DOS SFN", "LFN SFN", "DOS ATTR", "LFN ATTR", "DOS SIZE", "LFN SIZE", "LFN NAME"); 73 | if(findfirst("*.*", &ff, -1) == 0) do { 74 | printf("%14s|%14s|%08lx|%08lx|%08lx|%08lx%08lx|%s\n" 75 | , ff.ff_name, ff.ff_95.ff_shortname 76 | , (long)ff.ff_attr, (long)ff.ff_95.ff_attr95 77 | , ff.ff_size, ff.ff_95.ff_hisize, ff.ff_95.ff_losize 78 | , ff.ff_95.ff_longname); 79 | } while(findnext(&ff) == 0); 80 | 81 | puts("Entries retrieved with readdir():"); 82 | if((dirp = opendir(".")) == NULL) 83 | puts("Failed to opendir(.)"); 84 | else { 85 | while((dep = readdir(dirp)) != NULL) { 86 | printf("%ld. = ", telldir(dirp)); 87 | puts(dep->d_name); 88 | } 89 | closedir(dirp); 90 | } 91 | 92 | if(chdOK) 93 | chdir("..\\.."); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /IO95/TAGS: -------------------------------------------------------------------------------- 1 | !_TAG_FILE_FORMAT 2 /supported features/ 2 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted/ 3 | !_TAG_PROGRAM_AUTHOR Steve Kirkendall /kirkenda@cs.pdx.edu/ 4 | !_TAG_PROGRAM_NAME Elvis Ctags // 5 | !_TAG_PROGRAM_URL ftp://ftp.cs.pdx.edu/pub/elvis/README.html /official site/ 6 | !_TAG_PROGRAM_VERSION 2.1j-beta // 7 | FIND_FIRST FIND95.C 17;" file: d ln:17 8 | FIND_NEXT FIND95.C 18;" file: d ln:18 9 | IO95_NO_OPEN_PROTOTYPE OPEN95.C 23;" file: d ln:23 10 | MAXDRVLEN DIR95.C 29;" file: d ln:29 11 | MAXDRVLEN FLLPTH95.C 30;" file: d ln:30 12 | OPEN_CREATE OPEN95.C 26;" file: d ln:26 13 | OPEN_FLAGS OPEN95.C 29;" file: d ln:29 14 | OPEN_OPEN OPEN95.C 28;" file: d ln:28 15 | OPEN_SHARE OPEN95.C 30;" file: d ln:30 16 | OPEN_TRUNC OPEN95.C 27;" file: d ln:27 17 | PATTERN DIR95.C 28;" file: d ln:28 18 | callAPI MKDIR95.C /^static int callAPI(int fct, const char * const dnam)$/;" file: f ln:26 19 | callWin95 WIN95API.C /^int callWin95(int fct, struct REGPACK * const rp)$/;" f ln:29 20 | chdir95 MKDIR95.C /^int chdir95(const char * const dnam)$/;" f ln:45 21 | closedir95 DIR95.C /^closedir95(dirp)$/;" f ln:105 22 | conv95 FIND95.C /^static void conv95(FF_Block95 *ff)$/;" file: f ln:110 23 | conv95 L2S95.C /^static int conv95(int fct, const char * const fnam, char * const buf)$/;" file: f ln:28 24 | convDOS FIND95.C /^static void convDOS(FF_Block95 *ff)$/;" file: f ln:69 25 | find95 FIND95.C /^static int find95(char *name, FF_Block95 *ff, int attr)$/;" file: f ln:120 26 | findfile FIND95.C /^static int findfile(FF_Block95 *ff, int mode, char *name, int attr)$/;" file: f ln:83 27 | findfirst FIND95.C /^int findfirst(char *name, FF_Block95 *ff, int attr)$/;" f ln:53 28 | findfirst95 FIND95.C /^int findfirst95(char *name, FF_Block95 *ff, int attr)$/;" f ln:157 29 | findnext FIND95.C /^int findnext(FF_Block95 *ff)$/;" f ln:62 30 | findnext95 FIND95.C /^int findnext95(FF_Block95 *ff)$/;" f ln:166 31 | findstop95 FIND95.C /^void findstop95(FF_Block95 *ff)$/;" f ln:170 32 | fullpath95 FLLPTH95.C /^char *fullpath95(char * const Xbuffer, const char *path, int Xbuflen)$/;" f ln:42 33 | getcurdir95 GETCWD95.C /^int getcurdir95(int drive, char * const dir)$/;" f ln:41 34 | getcwd95 GETCWD95.C /^char * getcwd95(char *buf, int buflen)$/;" f ln:88 35 | getdcwd95 GETCWD95.C /^char * getdcwd95(int drive, char *buf, int buflen)$/;" f ln:58 36 | getdta FIND95.C /^char far *getdta(void)$/;" f ln:35 37 | lfn2sfn95 L2S95.C /^int lfn2sfn95(const char * const fnam, char * const buf)$/;" f ln:53 38 | mkdir95 MKDIR95.C /^int mkdir95(const char * const dnam)$/;" f ln:35 39 | next95 FIND95.C /^static int next95(FF_Block95 *ff)$/;" file: f ln:141 40 | open95 OPEN95.C /^int open95(char *fnam, long omode, int flags)$/;" f ln:147 41 | opendir95 DIR95.C /^opendir95(name)$/;" f ln:42 42 | rcsid DIR95.C /^static char const rcsid[] = $/;" file: v ln:32 43 | rcsid FIND95.C /^static char const rcsid[] = $/;" file: v ln:21 44 | rcsid FLLPTH95.C /^static char const rcsid[] = $/;" file: v ln:33 45 | rcsid GETCWD95.C /^static char const rcsid[] = $/;" file: v ln:29 46 | rcsid L2S95.C /^static char const rcsid[] = $/;" file: v ln:24 47 | rcsid MKDIR95.C /^static char const rcsid[] = $/;" file: v ln:22 48 | rcsid OPEN95.C /^static char const rcsid[] = $/;" file: v ln:33 49 | rcsid REN95.C /^static char const rcsid[] = $/;" file: v ln:14 50 | rcsid WIN95API.C /^static char const rcsid[] = $/;" file: v ln:25 51 | readdir95 DIR95.C /^struct dirent95 * readdir95(dirp)$/;" f ln:86 52 | rename95 REN95.C /^int rename95(const char * const oldnam, const char * const newnam)$/;" f ln:18 53 | rmdir95 MKDIR95.C /^int rmdir95(const char * const dnam)$/;" f ln:40 54 | seekdir95 DIR95.C /^seekdir95(dirp, pos)$/;" f ln:115 55 | setdta FIND95.C /^void setdta(char far *dta)$/;" f ln:26 56 | telldir95 DIR95.C /^telldir95(dirp)$/;" f ln:134 57 | truename95 L2S95.C /^int truename95(const char * const fnam, char * const buf)$/;" f ln:51 58 | -------------------------------------------------------------------------------- /IO95/TST.BAT: -------------------------------------------------------------------------------- 1 | @echo off 2 | type nul >longfilename1 3 | if exist longfilename2 del longfilename2 > nul 4 | if isdir longpathname rm -fr %@sfn[longpathname] 5 | t.exe 6 | -------------------------------------------------------------------------------- /IO95/TST.OUT: -------------------------------------------------------------------------------- 1 | SFN(longpathname\longerpath) = "D:\FREEDOS\SRC\IO95\LONGPA~1\LONGER~1" 2 | Current fullpath = "D:\FREEDOS\SRC\IO95\longpathname\longerpath" 3 | Entries found with findfirst/next loop: 4 | DOS SFN| LFN SFN|DOS ATTR|LFN ATTR|DOS SIZE| LFN SIZE|LFN NAME 5 | .| .|00000010|00000010|00000000|0000000000000000|. 6 | ..| ..|00000010|00000010|00000000|0000000000000000|.. 7 | LONGFI~1| LONGFI~1|00000020|00000020|0000269a|000000000000269a|longfilenameX 8 | Entries retrieved with readdir(): 9 | 1. = . 10 | 2. = .. 11 | 3. = longfilenameX 12 | -------------------------------------------------------------------------------- /IO95/TURBOC/MKLIB.BAT: -------------------------------------------------------------------------------- 1 | tcc -v -y -vi -c *.c >errlist 2 | del t.obj 3 | lib /c io95 -+ .\* , io95 4 | -------------------------------------------------------------------------------- /IO95/TURBOC/MKTEST.BAT: -------------------------------------------------------------------------------- 1 | tcc -v -y t.cc io95.lib 2 | -------------------------------------------------------------------------------- /IO95/WIN95API.C: -------------------------------------------------------------------------------- 1 | /* $RCSfile: WIN95API.C,v $ 2 | $Locker: $ $Name: not supported by cvs2svn $ $State: Exp $ 3 | 4 | int invokeWin95(int fct, struct REGPACK *rp) 5 | 6 | Invoke Win95/DOS function fct. It assumes that both APIs are the 7 | same except for the function number itself. 8 | 9 | *rp will hold the values of the successful call (either Win95 10 | or DOS). 11 | 12 | Return: 13 | 0: success 14 | else: failure 15 | 16 | $Log: not supported by cvs2svn $ 17 | Revision 1.2 2000/01/11 09:34:42 ska 18 | add: support Turbo C v2.01 19 | 20 | Revision 1.1 2000/01/11 09:10:09 ska 21 | Auto Check-in 22 | 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "io95.h" 31 | #include "io95_loc.h" 32 | 33 | #ifndef lint 34 | static char const rcsid[] = 35 | "$Id: WIN95API.C,v 1.1 2006-07-04 19:07:58 perditionc Exp $"; 36 | #endif 37 | 38 | int callWin95(int fct, struct REGPACK * const rp) 39 | { struct REGPACK r; /* temporary stack for the registers */ 40 | 41 | assert(rp); 42 | rp->r_flags = 1; /* asure that the carry is set */ 43 | memcpy(&r, rp, sizeof(r)); 44 | rp->r_ax = 0x7100 | fct; 45 | intr(0x21, rp); /* call Win95 API */ 46 | if((rp->r_flags & 1) && (rp->r_ax == 1 || rp->r_ax == 0x7100)) { 47 | /* try DOS API */ 48 | r.r_ax = fct << 8; 49 | memcpy(rp, &r, sizeof(r)); 50 | intr(0x21, rp); /* call DOS API */ 51 | } 52 | if(rp->r_flags & 1) 53 | return errno = rp->r_ax; /* keep error code */ 54 | return 0; /* success */ 55 | } 56 | -------------------------------------------------------------------------------- /IO95/io95.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/IO95/io95.bak -------------------------------------------------------------------------------- /IO95/makeio95.bat: -------------------------------------------------------------------------------- 1 | @if not exist io95.lib make -------------------------------------------------------------------------------- /LFNCHK.ASM: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; LFNCHK.ASM - Check wether LFN is supported for a specific drive. 3 | ;; 4 | ;; Copyright (C) 1999, 2000, 2001, Imre Leber. 5 | ;; 6 | ;; This program is free software; you can redistribute it and/or modify 7 | ;; it under the terms of the GNU General Public License as published by 8 | ;; the Free Software Foundation; either version 2 of the License, or 9 | ;; (at your option) any later version. 10 | ;; 11 | ;; This program is distributed in the hope that it will be useful, 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | ;; GNU General Public License for more details. 15 | ;; 16 | ;; You should have recieved a copy of the GNU General Public License 17 | ;; along with this program; if not, write to the Free Software 18 | ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | ;; 20 | ;; If you have any questions, comments, suggestions, or fixes please 21 | ;; email me at: imre.leber@worlonline.be 22 | ;; 23 | ;; 24 | 25 | %assign FILESYSLENGTH 32 ;; Sufficient according to RBIL 26 | 27 | segment _DATA class=DATA 28 | 29 | drive DB '?:\' 30 | 31 | filesys times FILESYSLENGTH DB 0 32 | 33 | segment _TEXT class=CODE 34 | 35 | ;========================================================================= 36 | ;=== CheckDriveOnLFN === 37 | ;===-------------------------------------------------------------------=== 38 | ;=== int CheckDriveOnLFN(char drive); === 39 | ;=== === 40 | ;=== Paramete: drive letter, eg. 'A' === 41 | ;=== === 42 | ;=== Returns: LFN supported on this disk: 0 === 43 | ;=== LFN supported on this disk: 1 === 44 | ;========================================================================= 45 | 46 | global _CheckDriveOnLFN 47 | _CheckDriveOnLFN: 48 | push es 49 | push di 50 | 51 | mov bx, sp 52 | mov ax, [ss:bx+06h] ;; Get parameter 53 | 54 | mov [drive], al ;; Complete drive spec 55 | 56 | mov ax, 71A0h ;; The function 57 | mov dx, drive ;; Pointer to drive string 58 | mov cx, FILESYSLENGTH ;; Set lentgh of buffer for file system string 59 | push ds ;; Far pointer 60 | pop es 61 | mov di, filesys ;; to file system string 62 | stc ;; Set carry for old DOS compatibility 63 | 64 | int 21h ;; Ask the system 65 | 66 | jc .NotSupported 67 | 68 | and bx, 16384 ;; Mask return value 69 | cmp bx, 0 ;; See if supported 70 | je .NotSupported 71 | 72 | mov ax, 1 ;; Function supported 73 | jmp short .EndOfProc 74 | 75 | .NotSupported: 76 | mov ax, 0 ;; Function not supported 77 | 78 | .EndOfProc: 79 | pop di 80 | pop es 81 | ret -------------------------------------------------------------------------------- /MAKEFILE: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for diskcopy 3 | # 4 | # Works for borland make. 5 | # 6 | # Works for GNU make only if you don't use the 16 bit dpmi version of the 7 | # borland tools. 8 | # 9 | 10 | ## change to reflect the real path where you installed tcc. 11 | #includepath = c:\tclite\include -| Only needed if tcc is incorrectly installed 12 | #libdir = c:\tclite\lib _| 13 | 14 | # libraries used with diskcopy 15 | catsdir = .\cats 16 | catslib = $(catsdir)\catsdb.lib 17 | includepath = $(includepath);$(catsdir) 18 | io95dir = .\io95 19 | io95lib = $(io95dir)\io95.lib 20 | 21 | libs = $(catslib) $(io95lib) 22 | 23 | compiler = tcc -c -I$(includepath) -Icats 24 | assembler = nasm #change to nasm16 on 8086/80286 25 | indenter = indenter.bat #indenter.bat 26 | 27 | #hlpoptions = 28 | hlpoptions = -DDEF_HELP 29 | 30 | recoptions = 31 | #recoptions = -DALL_RECOVERY_MODE 32 | 33 | #updateoptions = 34 | updateoptions = -DUPDATE_SERIALNUM 35 | 36 | backdrv = d: # just happens to be my ZIP drive 37 | # change to a: for backup to 38 | # floppy disk 39 | 40 | options = -w -O -Z $(hlpoptions) $(recoptions) $(updateoptions) 41 | 42 | sources = diskcopy.c drive.c ems.asm memtypes.c simplcpy.c xms.asm waitfinp.c tdrvcpy.c \ 43 | diskcopy.h drive.h ems.h memtypes.h misc.h xms.h waitfinp.h tdrvcpy.h \ 44 | mouse.asm mouse.h switchch.asm scanner.c parser.c scanner.h \ 45 | parser.h recovery.c datgen.c fastcopy.h boot.h \ 46 | fastcopy.c smdskcpy.c smdskcpy.h critical.asm hicritcl.asm critical.h \ 47 | lfnapi.c lfnapi.h lfnchk.asm serialnm.c 48 | 49 | objects = diskcopy.obj drive.obj ems.obj memtypes.obj simplcpy.obj xms.obj \ 50 | waitfinp.obj tdrvcpy.obj mouse.obj switchch.obj \ 51 | scanner.obj parser.obj recovery.obj \ 52 | exepath.obj datgen.obj fastcopy.obj smdskcpy.obj critical.obj \ 53 | hicritcl.obj lfnapi.obj lfnchk.obj serialnm.obj 54 | 55 | diskcopy.exe: $(sources) $(objects) 56 | @cd $(catsdir) 57 | @makecats 58 | @cd .. 59 | @cd $(io95dir) 60 | @makeio95 61 | @cd .. 62 | #@tlib diskcopy + diskcopy.obj 63 | @delete diskcopy.lib 64 | @tlib diskcopy + drive.obj 65 | @tlib diskcopy + ems.obj 66 | @tlib diskcopy + memtypes.obj 67 | @tlib diskcopy + simplcpy.obj 68 | @tlib diskcopy + xms.obj 69 | @tlib diskcopy + waitfinp.obj 70 | @tlib diskcopy + tdrvcpy.obj 71 | @tlib diskcopy + mouse.obj 72 | @tlib diskcopy + switchch.obj 73 | @tlib diskcopy + scanner.obj 74 | @tlib diskcopy + parser.obj 75 | @tlib diskcopy + recovery.obj 76 | @tlib diskcopy + exepath.obj 77 | @tlib diskcopy + datgen.obj 78 | @tlib diskcopy + fastcopy.obj 79 | @tlib diskcopy + smdskcpy.obj 80 | @tlib diskcopy + critical.obj 81 | @tlib diskcopy + hicritcl.obj 82 | @tlib diskcopy + lfnapi.obj 83 | @tlib diskcopy + lfnchk.obj 84 | @tlib diskcopy + serialnm.obj 85 | @tcc -M -ediskcopy.exe diskcopy.lib diskcopy.obj $(libs) 86 | @copy diskcopy.exe ..\..\bin 87 | @del diskcopy.lib 88 | @del diskcopy.bak 89 | 90 | diskcopy.obj: diskcopy.c drive.h diskcopy.h memtypes.h misc.h waitfinp.h\ 91 | tdrvcpy.h parser.h exepath.h nlsaspct.h simplcpy.h 92 | @$(compiler) $(options) diskcopy.c 93 | 94 | drive.obj: drive.c drive.h misc.h 95 | @$(compiler) $(options) drive.c 96 | 97 | ems.obj: ems.asm 98 | @$(assembler) ems.asm -f obj -o ems.obj 99 | 100 | memtypes.obj: memtypes.c memtypes.h xms.h ems.h diskcopy.h drive.h parser.h 101 | @$(compiler) $(options) memtypes.c 102 | 103 | simplcpy.obj: simplcpy.c simplcpy.h 104 | @$(compiler) $(options) simplcpy.c 105 | 106 | xms.obj: xms.asm 107 | @$(assembler) xms.asm -f obj -o xms.obj 108 | 109 | waitfinp.obj: waitfinp.c waitfinp.h mouse.h 110 | @$(compiler) $(options) waitfinp.c 111 | 112 | tdrvcpy.obj: tdrvcpy.c diskcopy.h tdrvcpy.h memtypes.h waitfinp.h drive.h \ 113 | nlsaspct.h 114 | @$(compiler) $(options) tdrvcpy.c 115 | 116 | scanner.obj: scanner.c diskcopy.h drive.h scanner.h parser.h datgen.h 117 | @$(compiler) $(options) scanner.c 118 | 119 | parser.obj: parser.c diskcopy.h drive.h scanner.h parser.h datgen.h \ 120 | nlsaspct.h 121 | @$(compiler) $(options) parser.c 122 | 123 | recovery.obj: recovery.c diskcopy.h drive.h nlsaspct.h 124 | @$(compiler) $(options) recovery.c 125 | 126 | exepath.obj: exepath.c exepath.h 127 | @$(compiler) $(options) exepath.c 128 | 129 | mouse.obj: mouse.asm 130 | @$(assembler) mouse.asm -f obj -o mouse.obj 131 | 132 | switchch.obj: switchch.asm 133 | @$(assembler) switchch.asm -f obj -o switchch.obj 134 | 135 | critical.obj: critical.asm 136 | @$(assembler) critical.asm -f obj -o critical.obj 137 | 138 | hicritcl.obj: critical.asm 139 | @$(assembler) hicritcl.asm -f obj -o hicritcl.obj 140 | 141 | datgen.obj: datgen.c datgen.h scanner.h parser.h drive.h fastcopy.h 142 | @$(compiler) $(options) datgen.c 143 | 144 | fastcopy.obj: fastcopy.c fastcopy.h drive.h diskcopy.h 145 | @$(compiler) $(options) fastcopy.c 146 | 147 | smdskcpy.obj: smdskcpy.c drive.h memtypes.h smdskcpy.h 148 | @$(compiler) $(options) smdskcpy.c 149 | 150 | lfnapi.obj: lfnapi.c drive.h lfnapi.h 151 | @$(compiler) $(options) lfnapi.c 152 | 153 | lfnchk.obj: lfnchk.asm 154 | @$(assembler) lfnchk.asm -f obj -o lfnchk.obj 155 | 156 | serialnm.obj: serialnm.c boot.h nlsaspct.h 157 | @$(compiler) $(options) serialnm.c 158 | 159 | clean: 160 | @cd $(catsdir) 161 | @make clean 162 | @cd .. 163 | @cd $(io95dir) 164 | @make clean 165 | @cd .. 166 | @delete diskcopy.exe 167 | @delete diskcopy.obj 168 | @delete drive.obj 169 | @delete ems.obj 170 | @delete memtypes.obj 171 | @delete simplcpy.obj 172 | @delete xms.obj 173 | @delete *.bak 174 | @delete waitfinp.obj 175 | @delete tdrvcpy.obj 176 | @delete mouse.obj 177 | @delete switchch.obj 178 | @delete drvtypes.obj 179 | @delete scanner.obj 180 | @delete parser.obj 181 | @delete exepath.obj 182 | @delete recovery.obj 183 | @delete fastcopy.obj 184 | @delete datgen.obj 185 | @delete smdskcpy.obj 186 | @delete lfnapi.obj 187 | @delete lfnchk.obj 188 | @delete serialnm.obj 189 | @delete critical.obj 190 | @delete hicritcl.obj 191 | 192 | backup: $(sources) #diskcopy.exe -- We assume that you know what need backing up 193 | @make clean 194 | @cls 195 | @echo Put your backup diskette in drive $(backdrv), and 196 | @pause 197 | @md $(backdrv)\diskcopy 198 | @xcopy \diskcopy $(backdrv)\diskcopy /s 199 | @echo Done. 200 | 201 | 202 | debugger: diskcopy.exe 203 | @delete diskcopy.exe 204 | @delete diskcopy.obj 205 | @delete drive.obj 206 | @delete memtypes.obj 207 | @delete simplcpy.obj 208 | @delete waitfinp.obj 209 | @delete tdrvcpy.obj 210 | @delete scanner.obj 211 | @delete parser.obj 212 | @delete exepath.obj 213 | @delete recovery.obj 214 | @delete datgen.obj 215 | @delete fastcopy.obj 216 | @delete smdskcpy.obj 217 | @delete lfnapi.obj 218 | @delete serialnm.obj 219 | 220 | indentation: $(sources) # requires GNU indent (DOS version) 221 | #all C files 222 | @$(indenter) diskcopy.c 223 | @$(indenter) drive.c 224 | @$(indenter) memtypes.c 225 | @$(indenter) simplcpy.c 226 | @$(indenter) waitfinp.c 227 | @$(indenter) tdrvcpy.c 228 | @$(indenter) parser.c 229 | @$(indenter) scanner.c 230 | @$(indenter) recovery.c 231 | @$(indenter) datgen.c 232 | @$(indenter) fastcopy.c 233 | @$(indenter) exepath.c 234 | @$(indenter) smdskcpy.c 235 | @$(indenter) lfnapi.c 236 | @$(indenter) serialnm.c 237 | #no asm files (indent doesn't work for assembly) 238 | #all header file 239 | @$(indenter) ems.h 240 | @$(indenter) critical.h 241 | @$(indenter) datgen.h 242 | @$(indenter) diskcopy.h 243 | @$(indenter) drive.h 244 | @$(indenter) exepath.h 245 | @$(indenter) fastcopy.h 246 | @$(indenter) memtypes.h 247 | @$(indenter) simplcpy.h 248 | @$(indenter) mouse.h 249 | @$(indenter) parser.h 250 | @$(indenter) scanner.h 251 | @$(indenter) tdrvcpy.h 252 | @$(indenter) waitfinp.h 253 | @$(indenter) xms.h 254 | @$(indenter) smdskcpy.h 255 | @$(indenter) lfnapi.h 256 | @$(indenter) serialnm.h 257 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is the source for FreeDOS diskcopy beta 0.92. To compile these file you 2 | will need: 3 | 4 | - nasm 0.98 (0.97 should work too). 5 | - turbo c 2.01, turbo c++ 1.01 or compatible compiler. 6 | - tlink. 7 | - tlib. 8 | 9 | So this program is completely compilable using only freely available software. 10 | For this purpose XMS.C (from beta 0.3) has been translated to XMS.ASM. 11 | 12 | Imre Leber (imre.leber@worldonline.be) 13 | -------------------------------------------------------------------------------- /SWITCHCH.ASM: -------------------------------------------------------------------------------- 1 | ; 2 | ; Switchch.asm - switchchar routine. 3 | ; Copyright (C) 2000, 2001 Imre Leber 4 | ; 5 | ; This program is free software; you can redistribute it and/or modify 6 | ; it under the terms of the GNU General Public License as published by 7 | ; the Free Software Foundation; either version 2 of the License, or 8 | ; (at your option) any later version. 9 | ; 10 | ; This program is distributed in the hope that it will be useful, 11 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ; GNU General Public License for more details. 14 | ; 15 | ; You should have received a copy of the GNU General Public License 16 | ; along with this program; if not, write to the Free Software 17 | ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | ; 19 | ; If you have any questions, comments, suggestions, or fixes please 20 | ; email me at: imre.leber@worldonline.be 21 | ; 22 | 23 | ;======================================================================== 24 | ;=== SwitchChar === 25 | ;===------------------------------------------------------------------=== 26 | ;=== Returns the DOS switch character. === 27 | ;======================================================================== 28 | 29 | segment _TEXT class=CODE 30 | 31 | global _SwitchChar 32 | _SwitchChar: 33 | 34 | mov ax, 3700h ; Get DOS switch character 35 | int 21h 36 | mov al, dl ; and return it. 37 | ret 38 | -------------------------------------------------------------------------------- /boot.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef BOOT_H_ 27 | #define BOOT_H_ 28 | 29 | /* The boot sector struct */ 30 | struct FAT32Specific 31 | { 32 | unsigned long SectorsPerFat; /* Sectors per FAT (32 bit) */ 33 | unsigned short ExtendedFlags; /* Bits 0-3 -- Zero-based number of active FAT. 34 | Only valid if mirroring is disabled. 35 | Bits 4-6 -- Reserved. 36 | Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs. 37 | -- 1 means only one FAT is active; it is the one referenced 38 | in bits 0-3. 39 | Bits 8-15 -- Reserved.*/ 40 | unsigned short FSVersion; /* File system version, MUST be 0. */ 41 | unsigned long RootCluster; /* First cluster of ROOT directory. */ 42 | unsigned short FSInfo; /* Sector number of FSINFO structure in the 43 | reserved area of the FAT32 volume. Usually 1.*/ 44 | unsigned short BackupBoot; /* Sector of boot sector backup */ 45 | unsigned char Reserved[12]; /* Should be all 0's */ 46 | unsigned char DriveNumber; /* BIOS drive number */ 47 | unsigned char Reserved1; /* Used by Windows NT (must be 0) */ 48 | unsigned char Signature; /* Indicates wether the following fields 49 | are present */ 50 | unsigned long VolumeID; /* Disk serial number */ 51 | unsigned char VolumeLabel[11]; /* Volume label */ 52 | unsigned char FSType[8]; /* Informational: "FAT12", "FAT16", "FAT32" */ 53 | /* Has nothing to do with FAT type 54 | determination */ 55 | unsigned char UnUsed[420]; 56 | unsigned short LastTwoBytes; /* Value of the last two bytes if 57 | BYTESPERSECTOR == 512 */ 58 | }; 59 | 60 | #if sizeof(struct FAT32Specific) != 476 61 | #error Wrong struct FAT32Specific 62 | #endif 63 | 64 | struct FAT1216Specific 65 | { 66 | unsigned char DriveNumber; /* BIOS drive number */ 67 | unsigned char Reserved; /* Used by Windows NT (must be 0) */ 68 | unsigned char Signature; /* Indicates wether the following fields 69 | are present */ 70 | unsigned char SerialNumber[4];/* Disk serial number */ 71 | unsigned char VolumeLabel[11];/* Volume label */ 72 | unsigned char FSType[8]; /* Informational: "FAT12", "FAT16", "FAT32" */ 73 | 74 | unsigned char UnUsed[448]; 75 | 76 | unsigned short LastTwoBytes; /* Value of the last two bytes if 77 | BYTESPERSECTOR == 512 */ 78 | }; 79 | 80 | #if sizeof(struct FAT1216Specific) != 476 81 | #error Wrong struct FAT1216Specific 82 | #endif 83 | 84 | union FATSpecific 85 | { 86 | struct FAT32Specific spc32; 87 | struct FAT1216Specific spc1216; 88 | }; 89 | 90 | struct BootSectorStruct 91 | { 92 | char Jump[3]; /* Jump instruction in boot routine. */ 93 | char Identification[8]; /* Identification code. */ 94 | unsigned short BytesPerSector; /* bytes per sector. */ 95 | unsigned char SectorsPerCluster; /* sectors per cluster. */ 96 | unsigned short ReservedSectors; /* number of reserved sectors. */ 97 | unsigned char Fats; /* number of fats. */ 98 | unsigned short NumberOfFiles; /* number of files or directories in */ 99 | /* the root directory. */ 100 | unsigned short NumberOfSectors; /* number of sectors in the volume. */ 101 | unsigned char descriptor; /* media descriptor. */ 102 | unsigned short SectorsPerFat; /* number of sectors per fat. */ 103 | unsigned short SectorsPerTrack; /* sectors per track. */ 104 | unsigned short Heads; /* number of read/write heads. */ 105 | unsigned long HiddenSectors; /* number of hidden sectors in the 106 | partition table */ 107 | unsigned long NumberOfSectors32; /* Number of sectors if the total 108 | number of sectors > 0xffff, or 109 | if this is FAT 32 */ 110 | union FATSpecific fs; /* Fields that are different for 111 | FAT 12/16 and FAT32 */ 112 | }; 113 | 114 | #if sizeof(struct BootSectorStruct) != 512 115 | #error WRONG BOOT SECTOR STRUCT LENGTH 116 | #endif 117 | 118 | /* A few simple defines */ 119 | #define BYTESPERSECTOR 512 120 | #define ENTRIESPERSECTOR (BYTESPERSECTOR / 32) 121 | 122 | /* This is not used in diskcopy, intended for defrag 123 | int ReadBootSector(RDWRHandle handle, struct BootSectorStruct* buffer); 124 | int WriteBootSector(RDWRHandle handle, struct BootSectorStruct* buffer); 125 | 126 | unsigned char GetSectorsPerCluster(RDWRHandle handle); 127 | unsigned short GetReservedSectors(RDWRHandle handle); 128 | unsigned char GetNumberOfFats(RDWRHandle handle); 129 | unsigned short GetNumberOfRootEntries(RDWRHandle handle); 130 | unsigned char GetMediaDescriptor(RDWRHandle handle); 131 | unsigned short GetNumberOfSectors(RDWRHandle handle); 132 | unsigned short GetSectorsPerFat(RDWRHandle handle); 133 | unsigned short GetSectorsPerTrack(RDWRHandle handle); 134 | unsigned short GetReadWriteHeads(RDWRHandle handle); 135 | unsigned short GetClustersInDataArea(RDWRHandle handle); 136 | */ 137 | 138 | #endif -------------------------------------------------------------------------------- /cats/CATGETS.C: -------------------------------------------------------------------------------- 1 | /* Functions that emulate UNIX catgets */ 2 | 3 | /* Copyright (C) 1999,2000,2001 Jim Hall */ 4 | 5 | /* 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | 22 | #include /* sprintf */ 23 | #include /* getenv */ 24 | #include /* strtok, strchr */ 25 | 26 | #ifndef HI_TECH_C 27 | #include /* fnmerge */ 28 | #endif 29 | 30 | #include "db.h" 31 | #include "catgets.h" 32 | 33 | #include "..\lfnapi.h" 34 | 35 | #define UNUSED(x) x=x 36 | 37 | /* External functions */ 38 | 39 | char *get_line (FILE *pfile, int continue_ch); 40 | 41 | 42 | /* Local prototypes */ 43 | 44 | int catread (char *catfile); /* Reads a catfile into the hash */ 45 | char *fix_ext(char *ext); /* Fixes the extension */ 46 | 47 | /* Globals */ 48 | 49 | nl_catd catalog = 0; /* Catalog descriptor, either 0 or 1 */ 50 | 51 | 52 | /* Functions */ 53 | 54 | char * 55 | catgets(nl_catd cat, int set_number, int message_number, 56 | char *message) 57 | { 58 | /* get message from a message catalog */ 59 | 60 | /* 'message' should really be const, but not when it is returned */ 61 | 62 | /* On success, catgets() returns a pointer to an internal buffer 63 | area containing the null-terminated message string. On failure, 64 | catgets() returns the value 'message'. */ 65 | 66 | char key[10]; 67 | db_t *ptr; 68 | 69 | /* Is this the same catalog we have in memory? */ 70 | 71 | if (cat != catalog) 72 | { 73 | return (message); 74 | } 75 | 76 | /* fetch the message that goes with the set/message number */ 77 | 78 | sprintf (key, "%d.%d", set_number, message_number); 79 | ptr = db_fetch (key); 80 | 81 | if (ptr) 82 | { 83 | return (ptr->value); 84 | } 85 | 86 | /* else */ 87 | 88 | return (message); 89 | } 90 | 91 | nl_catd 92 | catopen(char *name, int flag) 93 | { 94 | /* catopen() returns a message catalog descriptor of type nl_catd on 95 | success. On failure, it returns -1. */ 96 | 97 | char catfile[MAXPATH]; /* full path to the msg catalog */ 98 | char nlspath[MAXPATH]; /* value of %NLSPATH% */ 99 | char nlspath_lang[MAXPATH]; /* value of %NLSPATH%\%LANG% */ 100 | char *nlsptr; /* ptr to NLSPATH */ 101 | char *lang; /* ptr to LANG */ 102 | char lang_2[4]; /* 2-char version of %LANG% */ 103 | char *tok; /* pointer when using strtok */ 104 | 105 | /* 'flag' is completely ignored here. */ 106 | UNUSED(flag); 107 | 108 | /* Open the catalog file */ 109 | 110 | /* The value of `catalog' will be set based on catread */ 111 | 112 | if (catalog) 113 | { 114 | /* Already one open */ 115 | 116 | return (-1); 117 | } 118 | 119 | /* If the message catalog file name contains a directory separator, 120 | assume that this is a real path to the catalog file. Note that 121 | catread will return a true or false value based on its ability 122 | to read the catfile. */ 123 | 124 | if (strchr (name, '\\')) 125 | { 126 | /* first approximation: 'name' is a filename */ 127 | 128 | strcpy (catfile, name); 129 | catalog = catread (catfile); 130 | return (catalog); 131 | } 132 | 133 | /* If the message catalog file name does not contain a directory 134 | separator, then we need to try to locate the message catalog on 135 | our own. We will use several methods to find it. */ 136 | 137 | /* We will need the value of LANG, and may need a 2-letter abbrev of 138 | LANG later on, so get it now. */ 139 | 140 | lang = getenv ("LANG"); 141 | 142 | if (lang == NULL) 143 | { 144 | /* Return failure - we won't be able to locate the cat file */ 145 | return (-1); 146 | } 147 | 148 | if (lang[0] != '.') 149 | { 150 | lang_2[0] = '.'; 151 | strncpy (lang_2+1, lang, 2); 152 | lang_2[3] = '\0'; 153 | } 154 | else 155 | { 156 | strncpy (lang_2, lang, 2); 157 | lang_2[3] = '\0'; 158 | } 159 | 160 | /* step through NLSPATH */ 161 | 162 | nlsptr = getenv ("NLSPATH"); 163 | 164 | if (nlsptr == NULL) 165 | { 166 | /* Return failure - we won't be able to locate the cat file */ 167 | return (-1); 168 | } 169 | 170 | strcpy (nlspath, nlsptr); 171 | 172 | tok = strtok (nlspath, ";"); 173 | while (tok != NULL) 174 | { 175 | /* Convert path to SFN */ 176 | ConvertToSFN(tok, ENVVAR_ID); 177 | 178 | /* Try to find the catalog file in each path from NLSPATH */ 179 | 180 | /* Rule #1: %NLSPATH%\%LANG%\cat */ 181 | 182 | strcpy (nlspath_lang, nlspath); 183 | strcat (nlspath_lang, "\\"); 184 | strcat (nlspath_lang, lang); 185 | 186 | fnmerge (catfile, NULL, nlspath_lang, name, NULL); 187 | catalog = catread (catfile); 188 | if (catalog) 189 | { 190 | return (catalog); 191 | } 192 | 193 | /* Rule #2: %NLSPATH%\cat.%LANG% */ 194 | 195 | /* Jeremy Davis sent me a patch that forces a dot before the 196 | extension. But that was for _makepath. He also uses 197 | fnmerge, which seems to do this by itself (BC31). Can anyone 198 | confirm that TCC's fnmerge will also add the missing dot? */ 199 | 200 | fnmerge (catfile, NULL, GetSFN(ENVVAR_ID), name, lang_2); 201 | 202 | catalog = catread (catfile); 203 | if (catalog) 204 | { 205 | return (catalog); 206 | } 207 | 208 | /* Rule #3: if LANG looks to be in format "en-UK" then 209 | %NLSPATH%\cat.EN */ 210 | 211 | /* Jeremy Davis sent me a patch that forces a dot before the 212 | extension. But that was for _makepath. He also uses 213 | fnmerge, which seems to do this by itself (BC31). Can anyone 214 | confirm that TCC's fnmerge will also add the missing dot? */ 215 | 216 | if (lang[2] == '-') 217 | { 218 | fnmerge (catfile, NULL, GetSFN(ENVVAR_ID), name, lang_2); 219 | 220 | catalog = catread (catfile); 221 | if (catalog) 222 | { 223 | return (catalog); 224 | } 225 | } 226 | 227 | /* Grab next tok for the next while iteration */ 228 | 229 | tok = strtok (NULL, ";"); 230 | } /* while tok */ 231 | 232 | /* We could not find it. Return failure. */ 233 | 234 | return (0); 235 | } 236 | 237 | int 238 | catread (char *catfile) 239 | { 240 | FILE *pfile; /* pointer to the catfile */ 241 | char *key; /* part of key-value for hash */ 242 | char *value; /* part of key-value for hash */ 243 | char *str; /* the string read from the file */ 244 | 245 | /* Open the catfile for reading */ 246 | 247 | pfile = fopen (catfile, "r"); 248 | if (!pfile) 249 | { 250 | /* Cannot open the file. Return failure */ 251 | return (0); 252 | } 253 | 254 | /* Read the file into memory */ 255 | 256 | while ((str = get_line (pfile, 0)) != NULL) 257 | { 258 | /* Break into parts. Entries should be of the form: 259 | "1.2:This is a message" */ 260 | 261 | /* A line that starts with '#' is considered a comment, and will 262 | be thrown away without reading it. */ 263 | 264 | /* Assumes no blank lines */ 265 | 266 | if (str[0] != '#') 267 | { 268 | key = strtok (str, ":"); 269 | value = strtok (NULL, "\n"); 270 | 271 | db_insert (key, value); 272 | } /* if comment */ 273 | 274 | free (str); 275 | } /* while */ 276 | 277 | fclose (pfile); 278 | 279 | /* Return success */ 280 | 281 | return (1); 282 | } 283 | 284 | void 285 | catclose (nl_catd cat) 286 | { 287 | UNUSED(cat); 288 | 289 | /* close a message catalog */ 290 | 291 | catalog = 0; 292 | } 293 | -------------------------------------------------------------------------------- /cats/CATGETS.H: -------------------------------------------------------------------------------- 1 | /* $Id: CATGETS.H,v 1.1 2006-07-04 19:08:02 perditionc Exp $ */ 2 | 3 | /* Functions that emulate UNIX catgets */ 4 | 5 | /* Copyright (C) 1999,2000 Jim Hall */ 6 | 7 | /* 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | */ 22 | 23 | 24 | #ifndef _CATGETS_H 25 | #define _CATGETS_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* Data types */ 32 | 33 | typedef int nl_catd; 34 | 35 | 36 | /* Symbolic constants */ 37 | 38 | #define MCLoadBySet 0 /* not implemented */ 39 | #define MCLoadAll 0 /* not implemented */ 40 | 41 | 42 | /* Functions */ 43 | 44 | char * 45 | catgets(nl_catd cat, int set_number, int message_number, 46 | char *message); 47 | 48 | nl_catd 49 | catopen(char *name, int flag); 50 | 51 | void 52 | catclose (nl_catd cat); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* _CATGETS_H */ 59 | -------------------------------------------------------------------------------- /cats/DB.C: -------------------------------------------------------------------------------- 1 | /* A library of functions that implements a key-value database using a 2 | hash as the data storage/retrieval system. */ 3 | 4 | /* Copyright (C) 1999-2000 Jim Hall */ 5 | 6 | /* 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | /* The following functions are deprecated: db_init, db_free, db_compare */ 23 | 24 | /* Hash concept borrowed from _The C Programming Language_, Second Ed., 25 | BWK/DMR. */ 26 | 27 | 28 | #include 29 | #include /* malloc */ 30 | #include /* strdup */ 31 | 32 | #include "db.h" 33 | 34 | 35 | /* Function prototypes */ 36 | 37 | unsigned hash (char *s); 38 | 39 | 40 | /* Global variables */ 41 | 42 | static db_t *hashtab[HASHSIZE]; 43 | 44 | 45 | /* Functions */ 46 | 47 | /* hash() - My hash function. This is a little simple, but it will 48 | suffice. */ 49 | 50 | unsigned 51 | hash (char *s) 52 | { 53 | unsigned hashval; 54 | 55 | for (hashval = 0; *s != '\0'; s++) 56 | { 57 | /* assign a hash value (iterative) */ 58 | 59 | hashval = *s + 31 * hashval; 60 | } 61 | 62 | /* return the hash value */ 63 | 64 | return (hashval % HASHSIZE); 65 | } 66 | 67 | /* db_fetch() - Query the hash and return a struct that contains the 68 | key and the pointer. The calling function should not look beyond 69 | that. */ 70 | 71 | db_t * 72 | db_fetch (char *s) 73 | { 74 | db_t *db_ptr; 75 | 76 | for (db_ptr = hashtab[hash(s)]; db_ptr != NULL; db_ptr = db_ptr->next) 77 | { 78 | if (strcmp (s, db_ptr->key) == 0) 79 | { 80 | /* found it */ 81 | 82 | return (db_ptr); 83 | } 84 | } 85 | 86 | /* else, not found */ 87 | 88 | return (NULL); 89 | } 90 | 91 | /* db_insert() - Inserts a key,value pair into the hash. If the key 92 | already exists in the hash, the new value is NOT inserted. */ 93 | 94 | db_t * 95 | db_insert (char *key, char *value) 96 | { 97 | db_t *db_ptr; 98 | unsigned hashval; 99 | 100 | if ((db_ptr = db_fetch (key)) == NULL) 101 | { 102 | /* not found */ 103 | 104 | db_ptr = (db_t *) malloc (sizeof (*db_ptr)); 105 | 106 | if (db_ptr == NULL || (db_ptr->key = strdup (key)) == NULL) 107 | { 108 | return (NULL); 109 | } 110 | 111 | /* insert the key,value into the hash. */ 112 | 113 | hashval = hash(key); 114 | db_ptr->next = hashtab[hashval]; 115 | hashtab[hashval] = db_ptr; 116 | } 117 | 118 | else 119 | { 120 | /* already there */ 121 | 122 | free ((void *) db_ptr->value); 123 | } 124 | 125 | if ((db_ptr ->value = strdup (value)) == NULL) 126 | { 127 | return (NULL); 128 | } 129 | 130 | /* else */ 131 | 132 | return (db_ptr); 133 | } 134 | -------------------------------------------------------------------------------- /cats/DB.H: -------------------------------------------------------------------------------- 1 | /* $Id: DB.H,v 1.1 2006-07-04 19:08:02 perditionc Exp $ */ 2 | 3 | /* include file for a simple key-value db */ 4 | 5 | /* Copyright (C) 1999,2000 Jim Hall */ 6 | 7 | /* 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | */ 22 | 23 | 24 | #ifndef _DB_H 25 | #define _DB_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /* Symbolic constants */ 32 | 33 | #define HASHSIZE 101 34 | 35 | /* Typedefs and structs */ 36 | 37 | struct db_list{ 38 | struct db_list *next; 39 | char *key; 40 | char *value; 41 | }; 42 | 43 | typedef struct db_list db_t; 44 | 45 | 46 | /* Functions */ 47 | 48 | /* db.c */ 49 | 50 | int db_init (size_t init_size); 51 | int db_free (void); 52 | db_t *db_insert (char *key, char *value); 53 | int db_compare (db_t *p1, db_t *p2); 54 | db_t *db_fetch (char *key); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* _DB_H */ 61 | -------------------------------------------------------------------------------- /cats/GET_LINE.C: -------------------------------------------------------------------------------- 1 | /* get_line - this function will read a string from the file. The 2 | string may be broken across several lines using a "continue_ch" as 3 | the final character on a line. */ 4 | 5 | /* THIS FUNCTION WILL malloc() MEMORY FOR THE STRING. THE CALLING 6 | FUNCTION MUST free() THE STRING!! */ 7 | 8 | /* Copyright (C) 2000 Jim Hall */ 9 | 10 | /* 11 | This library is free software; you can redistribute it and/or 12 | modify it under the terms of the GNU Lesser General Public 13 | License as published by the Free Software Foundation; either 14 | version 2.1 of the License, or (at your option) any later version. 15 | 16 | This library is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public 22 | License along with this library; if not, write to the Free Software 23 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | */ 25 | 26 | #include 27 | #include /* malloc */ 28 | 29 | char * 30 | get_line (FILE *pfile, int continue_ch) 31 | { 32 | char *str; /* string that we will return */ 33 | char *tmp_str; 34 | int str_len; /* current length of the string */ 35 | int str_size; /* malloc size of the string */ 36 | int ch; 37 | int last_ch; 38 | 39 | /* this function will malloc memory for the string. the calling 40 | function must free() the string. */ 41 | 42 | str_len = 0; 43 | str_size = 10; 44 | str = malloc (sizeof (char) * str_size); 45 | 46 | if (!str) 47 | { 48 | /* failed! */ 49 | return (str); 50 | } 51 | 52 | /* now, read the string */ 53 | 54 | last_ch = '\0'; 55 | while ((ch = fgetc (pfile)) != EOF) 56 | { 57 | /* do we have enough room in the str for this ch? */ 58 | 59 | if (str_len >= str_size) 60 | { 61 | /* reallocate memory */ 62 | 63 | str_size *= 2; 64 | tmp_str = realloc (str, sizeof (char) * str_size); 65 | 66 | if (tmp_str) 67 | { 68 | /* move the pointer */ 69 | str = tmp_str; 70 | } 71 | 72 | else 73 | { 74 | /* failure! return what we have */ 75 | return (str); 76 | } 77 | } 78 | 79 | /* add the ch to the str */ 80 | 81 | if (ch == '\n') 82 | { 83 | /* is the string terminated? */ 84 | 85 | if (last_ch == continue_ch) 86 | { 87 | /* string is continued on next line ... ignore this ch 88 | and erase last_ch in the string */ 89 | str_len--; 90 | } 91 | 92 | else 93 | { 94 | /* string is terminated. return it. */ 95 | str[str_len++] = '\0'; 96 | return (str); 97 | } 98 | } 99 | 100 | else 101 | { 102 | str[str_len++] = ch; 103 | last_ch = ch; 104 | } 105 | 106 | } /* while */ 107 | 108 | /* we hit eof without eol. return what we have. */ 109 | 110 | return (NULL); 111 | } 112 | -------------------------------------------------------------------------------- /cats/makecats.bat: -------------------------------------------------------------------------------- 1 | @if not exist catsdb.lib make -------------------------------------------------------------------------------- /cats/makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for the cats library by Jim Hall (jhall@freedos.org). 3 | # 4 | 5 | compiler = tcc -c 6 | linker = tcc 7 | lib = tlib 8 | 9 | options = -w -Z -O -N 10 | 11 | objects = get_line.obj db.obj catgets.obj 12 | 13 | all: $(objects) 14 | @..\delete catsdb.lib 15 | @$(lib) catsdb.lib+ get_line.obj 16 | @$(lib) catsdb.lib+ db.obj 17 | @$(lib) catsdb.lib+ catgets.obj 18 | 19 | get_line.obj: get_line.c 20 | @$(compiler) $(options) get_line.c 21 | 22 | db.obj: db.c 23 | @$(compiler) $(options) db.c 24 | 25 | catgets.obj: catgets.c 26 | @$(compiler) $(options) catgets.c 27 | 28 | clean: 29 | @..\delete get_line.obj 30 | @..\delete db.obj 31 | @..\delete catgets.obj -------------------------------------------------------------------------------- /critical.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef CRITICAL_H_ 27 | #define CRITICAL_H_ 28 | 29 | /* Macro's to interpret the status code. */ 30 | 31 | /* Causes: */ 32 | #define WRITEPROTECTED 0 /* Medium is write protected. */ 33 | #define UNKNOWNDEVICE 1 /* Device unknown. */ 34 | #define DRIVENOTREADY 2 /* Drive not ready. */ 35 | #define UNKNOWNINSTRUCTION 3 /* Unknown instruction. */ 36 | #define CRC_ERROR 4 /* CRC error. */ 37 | #define WRONGLENGTH 5 /* Wrong length of data block. */ 38 | #define SEEKERROR 6 /* Seek error. */ 39 | #define UNKNOWNMEDIUM 7 /* Unknown medium. */ 40 | #define SECTOR_NOT_FOUND 8 /* Sector not found. */ 41 | #define NOPAPER 9 /* No paper left in printer. */ 42 | #define WRITEERROR 10 /* Write error. */ 43 | #define READERROR 11 /* Read error. */ 44 | #define GENERALFAILURE 12 /* General failure. */ 45 | 46 | /* Status values. */ 47 | 48 | #define ERRORONWRITE 0x01 /* Application where the error occured. */ 49 | /* 0 = read, 1 = write. */ 50 | 51 | #define ERRORRANGE 0x06 /* Range involved. */ 52 | /* 0 = system data. */ 53 | /* 1 = FAT. */ 54 | /* 2 = directory. */ 55 | /* 3 = data range. */ 56 | 57 | #define ABORTALLOWED 0x08 /* Abort allowed. */ 58 | #define RETRYALLOWED 0x10 /* Retry allowed. */ 59 | #define IGNOREALLOWED 0x20 /* Ignore allowed. */ 60 | 61 | #define IGNORE 0x00 62 | #define RETRY 0x01 63 | #define ABORTIT 0x02 64 | #define FAIL 0x03 65 | 66 | /* In critical.asm */ 67 | void SetCriticalHandler (int (*handler) (int status)); 68 | void RenewCriticalHandler (int (*handler) (int status)); 69 | 70 | /* In hicritcl.asm */ 71 | void CriticalHandlerOn (void); 72 | int CriticalErrorOccured (void); 73 | int GetCriticalCause (void); 74 | int GetCriticalStatus (void); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /datgen.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/datgen.c -------------------------------------------------------------------------------- /datgen.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef DATGEN_H_ 27 | #define DATGEN_H_ 28 | 29 | int ExploreDATFile (struct IniParserStruct *ParsedData); 30 | int MakeDATFile (struct IniParserStruct *ParsedData); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /diskcopy.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2004, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef DISKCOPY_H_ 27 | #define DISKCOPY_H_ 28 | 29 | #define ON 1 30 | #define OFF 0 31 | 32 | /* Error levels. */ 33 | #define COPYSUCCESS 0 34 | #define NONFATAL 1 35 | #define CTRL_C 2 36 | #define CRITICAL 3 37 | #define INITERROR 4 38 | 39 | #define READIMAGE 1 /* Numbering is important. */ 40 | #define WRITEIMAGE 2 41 | 42 | #define EXISTS 0 43 | #define READPERMISSION 4 /* Numbering is important. */ 44 | #define WRITEPERMISSION 2 45 | 46 | #define ABORT 0 47 | 48 | #define DISKREADING 0 49 | #define DISKWRITING 0 50 | #define VERIFICATION 1 51 | 52 | #define VERSION "beta 0.94" 53 | 54 | #define Beep() printf("\a") 55 | 56 | /* Function to show help. */ 57 | void ShowHelp (char switchchar); 58 | 59 | int RegularDiskCopy (char sdrive, char tdrive, 60 | int audible, int HardDiskOk, int informative); 61 | 62 | int ReadImageFile (char *ImageFile, char drive); 63 | int WriteImageFile (char *ImageFile, char drive); 64 | 65 | void OnExit (void); 66 | int OnCBreak (void); 67 | 68 | void ReadSectors (int drive, int nsects, int lsect, void *buffer, 69 | int bytespersector); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /doc/diskcopy.lsm: -------------------------------------------------------------------------------- 1 | Begin3 2 | Title: diskcopy 3 | Version: beta 0.94 4 | Entered-date: 05AUG2004 5 | Description: copy one disk or image file to an other 6 | Keywords: freedos,disk,diskcopy,copy 7 | Author: "Imre Leber" 8 | Maintained-by: "Imre Leber" 9 | Primary-site: http://users.pandora.be/imre/FreeDOS/ 10 | Alternative-site: http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/dos/diskcopy/ 11 | Original-site: 12 | Platforms: dos 13 | Copying-policy: GPL 14 | End 15 | -------------------------------------------------------------------------------- /drive.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MS-DOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | module: drive.c - file with drive functions. 25 | 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #ifndef HI_TECH_C 33 | #include 34 | #else 35 | #include 36 | #endif 37 | 38 | #ifndef HI_TECH_C 39 | #define CURRENT_DRIVE (getdisk() + 'A') 40 | #else 41 | #define CURRENT_DRIVE (*(getdrv())) 42 | #endif 43 | 44 | #include "misc.h" 45 | #include "drive.h" 46 | 47 | static int 48 | HasAllFloppyForm (char *drive) 49 | { 50 | int drv; 51 | 52 | if (strlen (drive) != 2) 53 | return FALSE; 54 | 55 | drv = toupper (drive[0]); 56 | if ((drv >= 'A') && (drv <= 'Z') && (drive[1] == ':')) 57 | return TRUE; 58 | 59 | return FALSE; 60 | } 61 | 62 | int 63 | HasFloppyForm (char *drive) 64 | { 65 | return HasAllFloppyForm(drive); 66 | } 67 | 68 | int 69 | IsFile (char *x) 70 | { 71 | return (!HasAllFloppyForm (x) && x[0] != '/' && x[0] != SwitchChar ()); 72 | } 73 | 74 | int 75 | IsCopyToSameDisk (char *drvorfle1, char *drvorfle2) 76 | { 77 | /* diskcopy a: a: */ 78 | if (HasAllFloppyForm (drvorfle1) && HasAllFloppyForm (drvorfle2)) 79 | return FALSE; 80 | 81 | /* diskcopy a: a:test.img */ 82 | if (HasAllFloppyForm (drvorfle1)) 83 | return IsCopyToSameDisk (drvorfle2, drvorfle1); 84 | 85 | /* diskcopy a:test.img a: */ 86 | if (HasAllFloppyForm (drvorfle2)) 87 | if (*drvorfle1 && (drvorfle1[1] == ':')) 88 | /* diskcopy a:test.img a: */ 89 | return toupper (*drvorfle1) == toupper (*drvorfle2); 90 | else 91 | /* A:\> diskcopy test.img a: */ 92 | return (CURRENT_DRIVE == toupper (drvorfle2[0])); 93 | 94 | return FALSE; /* Both are files */ 95 | } 96 | 97 | char 98 | GetDiskFromPathName (char *path) 99 | { 100 | if (HasAllFloppyForm (path) || (path && (path[1] == ':'))) 101 | return path[0]; 102 | else 103 | return tolower(CURRENT_DRIVE); 104 | } 105 | -------------------------------------------------------------------------------- /drive.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef DRIVE_H_ 27 | #define DRIVE_H_ 28 | 29 | #ifndef TRUE /* You never know. */ 30 | #define TRUE 1 31 | #endif 32 | 33 | #ifndef FALSE 34 | #define FALSE 0 35 | #endif 36 | 37 | int HasFloppyForm (char *drive); 38 | int IsFile (char *x); 39 | int IsCopyToSameDisk (char *drvorfle1, char *drvorfle2); 40 | 41 | unsigned GetFullClusterCount (int disk); 42 | 43 | char GetDiskFromPathName (char *path); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /ems.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | /* 27 | ** EMS.H 28 | ** 29 | ** Header file Expanded Memory Routines 30 | */ 31 | 32 | #ifndef EMS_H_ 33 | #define EMS_H_ 34 | 35 | #define EMS_PAGE_SIZE 16384 /* Each page is this size */ 36 | 37 | unsigned int EMSbaseaddress (void); 38 | int EMSversion (void); 39 | int EMSstatus (void); 40 | int EMSpages (void); 41 | int EMSalloc (int pages); 42 | int EMSfree (int handle); 43 | int EMSmap (int bank, int handle, int page); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /exepath.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MS-DOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worlonline.be 23 | 24 | module: exepath.c - keep track of the executables path. 25 | 26 | */ 27 | 28 | #include 29 | 30 | #include "exepath.h" 31 | 32 | static char *ExecutablesPath; 33 | 34 | void 35 | SetExePath (char *exepath) 36 | { 37 | ExecutablesPath = exepath; 38 | } 39 | 40 | void 41 | GetExePath (char *buffer, size_t n) 42 | { 43 | int i; 44 | 45 | if (strlen (ExecutablesPath) > n) 46 | { 47 | buffer[0] = 0; 48 | } 49 | 50 | strcpy (buffer, ExecutablesPath); 51 | 52 | for (i = strlen (buffer) - 1; i >= 0; i--) 53 | if (buffer[i] == '\\') 54 | { 55 | buffer[i + 1] = '\0'; 56 | break; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /exepath.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef EXEPATH_H_ 27 | #define EXEPATH_H_ 28 | 29 | void SetExePath (char *exepath); 30 | void GetExePath (char *buffer, size_t n); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /fastcopy.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "drive.h" 34 | #include "boot.h" 35 | #include "fastcopy.h" 36 | 37 | static int PerformFastCopy = FALSE; 38 | 39 | static char far *FatInfo = NULL; /* FAT information */ 40 | static struct BootSectorStruct bsect; /* Keep boot sector info handy */ 41 | 42 | /* Cached values */ 43 | static unsigned long DataStart = 0; /* At least this one is only calculated 44 | once */ 45 | 46 | unsigned long 47 | GetDataStart (void) /* in sectors */ 48 | { 49 | if (!DataStart) 50 | DataStart = 51 | bsect.ReservedSectors + /* Skip boot sector, */ 52 | (bsect.Fats * bsect.SectorsPerFat) + /* FAT(s), */ 53 | (bsect.NumberOfFiles / ENTRIESPERSECTOR); /* and root dir */ 54 | 55 | return DataStart; 56 | } 57 | 58 | unsigned 59 | DataSectorToCluster (unsigned long sector) 60 | { 61 | unsigned long datastart = GetDataStart (); 62 | 63 | return (unsigned) ((sector + (2 * bsect.SectorsPerCluster) - datastart) / 64 | bsect.SectorsPerCluster); 65 | } 66 | 67 | static int 68 | IsSectorFilled (unsigned long sector) /* Remember it is for FAT12 */ 69 | { 70 | unsigned cluster1, label; 71 | unsigned cluster = DataSectorToCluster (sector); 72 | 73 | cluster1 = cluster + (cluster >> 1); /* multiply cluster * 1.5 */ 74 | label = *((unsigned far *) (FatInfo + cluster1)); 75 | 76 | if ((cluster & 1) == 0) /* If cluster is even */ 77 | label &= 0x0fff; 78 | else 79 | label &= 0xfff0; 80 | 81 | return (label != 0); 82 | } 83 | 84 | /* Return the meaningfull bytes on the disk */ 85 | unsigned long 86 | GetDiskFilledSize (unsigned blocksize) 87 | { 88 | unsigned sectorsperblock, j; 89 | unsigned long count = 0, blocks, i; 90 | 91 | if (!PerformFastCopy) 92 | return (unsigned long) bsect.NumberOfSectors * bsect.BytesPerSector; 93 | 94 | /* Calculate the number of blocks in the volume */ 95 | blocks = ((unsigned long) bsect.NumberOfSectors * bsect.BytesPerSector) / blocksize; 96 | 97 | /* Calculate the number of sectors per block of 32Kb */ 98 | sectorsperblock = blocksize / bsect.BytesPerSector; 99 | 100 | /* Count the number of filled blocks */ 101 | 102 | /* Take into account system area of disk */ 103 | count = (GetDataStart () / sectorsperblock) + 104 | ((GetDataStart () % sectorsperblock) != 0); 105 | 106 | /* Data area */ 107 | for (i = count; i < blocks; i++) 108 | for (j = 0; j < sectorsperblock; j++) 109 | if (IsSectorFilled (i * sectorsperblock + j)) 110 | { 111 | count++; 112 | break; 113 | } 114 | 115 | return count * blocksize; 116 | } 117 | 118 | int 119 | IsSectorUsed (unsigned long sector) 120 | { 121 | if (!PerformFastCopy) 122 | return TRUE; /* Always copy in full method */ 123 | 124 | if (sector <= GetDataStart ()) 125 | return TRUE; 126 | 127 | return IsSectorFilled (sector); 128 | } 129 | 130 | static int 131 | FileReader (int handle, int nsects, long lsect, void *buffer) 132 | { 133 | int size = nsects * BYTESPERSECTOR; 134 | 135 | lseek (handle, lsect * BYTESPERSECTOR, SEEK_SET); 136 | return read (handle, buffer, size) != size; /* Return 0 on success */ 137 | } 138 | 139 | static int 140 | ReadBootInfo (int drive, struct dfree *free, 141 | int (*readfunc) (int drive, int nsects, long lsect, 142 | void *buffer)) 143 | { 144 | if (readfunc (drive, 1, 0, (void *) &bsect) != 0) 145 | return FALSE; 146 | 147 | free->df_total = bsect.NumberOfSectors / bsect.SectorsPerCluster; 148 | free->df_bsec = BYTESPERSECTOR; /* bsect.BytesPerSector HAS TO BE 512 */ 149 | free->df_sclus = bsect.SectorsPerCluster; 150 | 151 | return TRUE; 152 | } 153 | 154 | int 155 | DiskReadBootInfo (int drive, struct dfree *free) 156 | { 157 | return ReadBootInfo (drive, free, absread); 158 | } 159 | 160 | int 161 | FileReadBootInfo (char *file, struct dfree *free) 162 | { 163 | int handle, result; 164 | 165 | handle = open (file, O_RDONLY | O_BINARY); 166 | if (handle == -1) 167 | return FALSE; 168 | 169 | result = ReadBootInfo (handle, free, FileReader); 170 | 171 | close (handle); 172 | 173 | return result; 174 | } 175 | 176 | static int 177 | ReadFatInfo (int driveorfile, 178 | int (*readfunc) (int drive, int nsects, long lsect, 179 | void *buffer)) 180 | { 181 | int i; 182 | char buf[512]; 183 | unsigned long FirstFatSector; 184 | unsigned segment, offset; 185 | 186 | /* Allocate memory for fat info (far heap) */ 187 | ReleaseFatInfo (); /* But first release any previously allocated memory. */ 188 | FatInfo = farmalloc ((unsigned long) bsect.SectorsPerFat * BYTESPERSECTOR); 189 | if (!FatInfo) 190 | return FALSE; 191 | 192 | /* Read FAT in memory */ 193 | FirstFatSector = bsect.ReservedSectors; /* FAT starts right after boot */ 194 | segment = FP_SEG (FatInfo); 195 | offset = FP_OFF (FatInfo); 196 | segment = segment + (offset / 16); 197 | offset = offset % 16; 198 | 199 | for (i = 0; i < bsect.SectorsPerFat; i++) 200 | { 201 | if (readfunc (driveorfile, 1, FirstFatSector + i, (void *) buf) != 0) 202 | { 203 | farfree (FatInfo); 204 | FatInfo = NULL; 205 | return FALSE; 206 | } 207 | movedata (FP_SEG (buf), FP_OFF (buf), 208 | segment, offset, BYTESPERSECTOR); 209 | segment += BYTESPERSECTOR / 16; 210 | } 211 | 212 | return TRUE; 213 | } 214 | 215 | int 216 | FileReadFatInfo (char *file) 217 | { 218 | int handle, result; 219 | 220 | handle = open (file, O_RDONLY | O_BINARY); 221 | if (handle == -1) 222 | return FALSE; 223 | 224 | result = ReadFatInfo (handle, FileReader); 225 | 226 | close (handle); 227 | 228 | return result; 229 | } 230 | 231 | int 232 | DiskReadFatInfo (int drive) 233 | { 234 | return ReadFatInfo (drive, absread); 235 | } 236 | 237 | void 238 | SetCopySpeed (int method) 239 | { 240 | PerformFastCopy = (method == FAST); 241 | } 242 | 243 | int 244 | IsDiskReadRequired (unsigned long beginsector, int amount) 245 | { 246 | int i; 247 | 248 | if (!PerformFastCopy) 249 | return TRUE; /* Always copy in full method */ 250 | 251 | /* Always copy system area of disk */ 252 | if (beginsector <= GetDataStart ()) 253 | return TRUE; 254 | 255 | for (i = 0; i < amount; i++) 256 | if (IsSectorFilled (beginsector + i)) 257 | return TRUE; 258 | 259 | return FALSE; /* Don't read sector from disk */ 260 | } 261 | 262 | void 263 | ReleaseFatInfo (void) 264 | { 265 | if (FatInfo) 266 | farfree (FatInfo); 267 | } 268 | 269 | /************************************************************ 270 | ** Determine FAT type 271 | ************************************************************* 272 | ** Returns the kind of FAT being used. 273 | ** 274 | ** Notice that the previous function returns the FAT 275 | ** determination string the value returned there is only 276 | ** informative and has no real value. The type of FAT is ONLY 277 | ** determined by the cluster number. 278 | *************************************************************/ 279 | int DetermineFATType(void) 280 | { 281 | unsigned long RootDirSectors, FatSize, TotalSectors, DataSector; 282 | unsigned long CountOfClusters; 283 | 284 | RootDirSectors = ((bsect.NumberOfFiles * 32) + 285 | (bsect.BytesPerSector-1)) / 286 | (bsect.BytesPerSector); 287 | 288 | if (bsect.SectorsPerFat != 0) 289 | FatSize = bsect.SectorsPerFat; 290 | else 291 | FatSize = bsect.fs.spc32.SectorsPerFat; 292 | 293 | if (bsect.NumberOfSectors != 0) 294 | TotalSectors = bsect.NumberOfSectors; 295 | else 296 | TotalSectors = bsect.NumberOfSectors32; 297 | 298 | DataSector = TotalSectors - 299 | (bsect.ReservedSectors + 300 | (bsect.Fats * FatSize) + 301 | RootDirSectors); 302 | 303 | CountOfClusters = DataSector / bsect.SectorsPerCluster; 304 | 305 | if (CountOfClusters < 4085) 306 | { 307 | return FAT12; 308 | } 309 | else if (CountOfClusters < 65525L) 310 | { 311 | return FAT16; 312 | } 313 | else 314 | { 315 | return FAT32; 316 | } 317 | } -------------------------------------------------------------------------------- /fastcopy.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef FASTCOPY_H_ 27 | #define FASTCOPY_H_ 28 | 29 | #define FULL 11 30 | #define FAST 22 31 | 32 | #define FAT12 12 33 | #define FAT16 16 34 | #define FAT32 32 35 | 36 | int DiskReadFatInfo (int drive); 37 | int FileReadFatInfo (char *file); 38 | 39 | void SetCopySpeed (int method); 40 | int IsDiskReadRequired (unsigned long beginsector, int amount); 41 | void ReleaseFatInfo (void); 42 | int DiskReadBootInfo (int drive, struct dfree *free); 43 | int FileReadBootInfo (char *file, struct dfree *free); 44 | 45 | unsigned long GetDiskFilledSize (unsigned blocksize); 46 | 47 | 48 | int IsSectorUsed (unsigned long sector); 49 | 50 | int DetermineFATType(void); 51 | 52 | #endif -------------------------------------------------------------------------------- /indenter.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | @indent %1 -o indent.$$$ 3 | @del %1 4 | @ren indent.$$$ %1 5 | -------------------------------------------------------------------------------- /lfnapi.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worlonline.be 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #ifndef HI_TECH_C 29 | #include 30 | #endif 31 | #include 32 | 33 | #include "io95\io95.h" 34 | #include "lfnapi.h" 35 | #include "drive.h" 36 | #include "diskcopy.h" 37 | #include "critical.h" 38 | 39 | static char ShortNames[MAXSFNS][MAXPATH95]; 40 | static char LongNames[MAXSFNS][MAXPATH95]; 41 | 42 | static char scratchpad[MAXPATH95]; 43 | 44 | static struct LFNAttribute Attributes[MAXSFNS]; 45 | 46 | static int 47 | IsLFNSupported (char *filename) 48 | { 49 | int result; 50 | 51 | if (filename && filename[0] && (filename[1] == ':')) 52 | result = CheckDriveOnLFN (filename[0]); 53 | else 54 | result = CheckDriveOnLFN (getdisk () + 'A'); 55 | 56 | if (CriticalErrorOccured ()) 57 | return MAYBE; /* If this caused a reaction, LFN would be supported. 58 | Maybe not on the indicated drive though. */ 59 | else 60 | return result; 61 | } 62 | 63 | static void 64 | GenerateUniqueCurrentSFN (char *sfnpath) 65 | { 66 | char sfn[9] = "AAAAAAAA\0"; 67 | static int counter1 = 0; 68 | static int counter2 = 0; 69 | int len = strlen (sfnpath); 70 | 71 | do 72 | { 73 | memset (sfn, 'A', 8); 74 | itoa (counter1++, sfn, 16); 75 | sfn[strlen (sfn)] = 'A'; 76 | 77 | if (counter1 == 32767) 78 | { 79 | counter1 = 0; 80 | counter2++; 81 | } 82 | 83 | itoa (counter2, sfn + 4, 16); 84 | sfnpath[len] = '\0'; 85 | } 86 | while (access (strcat (sfnpath, sfn), EXISTS) == 0); 87 | } 88 | 89 | static void 90 | GenerateUniqueSFN (char *lfn, char *sfn) 91 | { 92 | char *p; 93 | int found = FALSE; 94 | 95 | /* Copy path to sfn. */ 96 | strcpy (sfn, lfn); 97 | for (p = sfn + strlen (sfn); p != sfn; p--) 98 | if ((*p == '\\') || (*p == ':')) 99 | { 100 | *(p + 1) = '\0'; 101 | found = TRUE; 102 | } 103 | 104 | if (!found) 105 | *sfn = 0; 106 | 107 | /* Add imaginary long filename. */ 108 | GenerateUniqueCurrentSFN (sfn); 109 | } 110 | 111 | void 112 | InitLFNAPI (void) 113 | { 114 | int i; 115 | 116 | for (i = 0; i < MAXSFNS; i++) 117 | { 118 | ShortNames[i][0] = LongNames[i][0] = '\0'; 119 | Attributes[i].output = FALSE; 120 | } 121 | } 122 | 123 | void 124 | ConvertToSFN (char *lfn, int index) 125 | { 126 | int supported; 127 | ShortNames[index][0] = '\0'; /* important */ 128 | 129 | supported = IsLFNSupported (lfn); 130 | 131 | if (supported == TRUE) 132 | { 133 | if (lfn2sfn95 (lfn, ShortNames[index]) != 0) 134 | ShortNames[index][0] = '\0'; 135 | } 136 | else if (supported == MAYBE) 137 | ShortNames[index][0] = '\0'; /* Don't know wether LFN is supported. */ 138 | else 139 | strcpy (ShortNames[index], lfn); 140 | 141 | strcpy (LongNames[index], lfn); 142 | } 143 | 144 | char * 145 | GetSFN (int index) 146 | { 147 | int supported; 148 | 149 | if (ShortNames[index][0] == 0) 150 | { 151 | /* At this time the disk has to be in the station */ 152 | supported = IsLFNSupported (LongNames[index]); 153 | if (supported == TRUE) 154 | { 155 | if (LongNames[index][0] != 0) 156 | GenerateUniqueSFN (LongNames[index], ShortNames[index]); 157 | else 158 | return NULL; 159 | } 160 | else if (supported == MAYBE) 161 | return NULL; /* Disk not in drive */ 162 | else 163 | strcpy (ShortNames[index], LongNames[index]); /* LFN not supported after all. */ 164 | } 165 | 166 | return ShortNames[index]; 167 | } 168 | 169 | void 170 | SetLFNAttribute (struct LFNAttribute *attrib, int index) 171 | { 172 | memcpy (&Attributes[index], attrib, sizeof (struct LFNAttribute)); 173 | } 174 | 175 | char * 176 | GetLFN (int index) 177 | { 178 | return LongNames[index]; 179 | } 180 | 181 | void 182 | SynchronizeLFNs (void) 183 | { 184 | int i; 185 | 186 | for (i = 0; i < MAXSFNS; i++) 187 | { 188 | if ((LongNames[i] != '\0') && (ShortNames[i] != '\0') && 189 | (IsLFNSupported (LongNames[i]) == TRUE)) 190 | { 191 | lfn2sfn95 (LongNames[i], scratchpad); 192 | 193 | if ((strcmpi (ShortNames[i], scratchpad) != 0) && 194 | (Attributes[i].output)) 195 | { 196 | if (!rename95 (ShortNames[i], LongNames[i])) 197 | { 198 | rename (ShortNames[i], LongNames[i]); 199 | strcpy (ShortNames[i], LongNames[i]); 200 | } 201 | else 202 | lfn2sfn95 (LongNames[i], ShortNames[i]); 203 | } 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /lfnapi.h: -------------------------------------------------------------------------------- 1 | #ifndef LFNAPI_H_ 2 | #define LFNAPI_H_ 3 | 4 | #define MAXSFNS 3 5 | #define INFILE_ID 0 6 | #define OUTFILE_ID 1 7 | #define ENVVAR_ID 2 8 | 9 | #define MAYBE 2 10 | 11 | struct LFNAttribute 12 | { 13 | int output; 14 | }; 15 | 16 | void InitLFNAPI (void); 17 | void ConvertToSFN (char *lfn, int index); 18 | char *GetSFN (int index); 19 | void SetLFNAttribute (struct LFNAttribute *attrib, int index); 20 | void SaveLFN (char *lfn, int index); 21 | char *GetLFN (int index); 22 | void SynchronizeLFNs (void); 23 | 24 | /* In LFNCHK.ASM */ 25 | int CheckDriveOnLFN (char drive); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /memtypes.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/memtypes.c -------------------------------------------------------------------------------- /memtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef MEMTYPES_H_ 27 | #define MEMTYPES_H_ 28 | 29 | /* Memory types. */ 30 | #define EMS 4 31 | #define XMS 3 32 | #define HARDDISK 2 33 | #define BUFFERS 1 34 | #define NONEFITTING 0 35 | #define UNALLOCATED 0 36 | 37 | #define READING 0 38 | #define WRITING 1 39 | 40 | #define READ 0 41 | #define WRITE 1 42 | 43 | #define BUFFERSIZE 16384u 44 | #define BYTESPERSECTOR 512 45 | #define TOCOPYSECTORS (BUFFERSIZE / BYTESPERSECTOR) 46 | 47 | #define DISKTOSMALL -2 48 | 49 | int InitializeFittingMemory (unsigned long size, int HardDiskOk, 50 | unsigned long *allocated, 51 | char sdrv, char tdrv); 52 | int ReadMemoryBlock (char *buffer, unsigned size); 53 | int WriteMemoryBlock (char *buffer, unsigned size); 54 | 55 | void PrepareForReading (void); 56 | void PrepareForWriting (void); 57 | 58 | void ReleaseMemory (void); 59 | 60 | int SetImageFile (char *imagefile, int ImageModus, unsigned long filesize); 61 | void SetErrorStopped (void); 62 | int DiskLargeEnough (char *imagefile, unsigned long floppysize); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef MISC_H_ 27 | #define MISC_H_ 28 | 29 | char SwitchChar (void); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /mouse.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef MOUSE_H_ 27 | #define MOUSE_H_ 28 | 29 | #define LEFTBUTTON 1 30 | #define RIGHTBUTTON 2 31 | #define MIDDLEBUTTON 4 32 | 33 | #define LEFTBUTTONACCENT 0 34 | #define RIGHTBUTTONACCENT 1 35 | #define MIDDLEBUTTONACCENT 2 36 | 37 | #define SOTWARECURSOR 0 38 | #define HARDWARECURSOR 1 39 | 40 | /* Mouse.asm */ 41 | 42 | int InitMouse (void); 43 | int MousePresent (void); 44 | void ShowMouse (void); 45 | void HideMouse (void); 46 | int WhereMouse (int *x, int *y); 47 | void MouseGotoXY (int x, int y); 48 | int CountButtonPresses (int button, int *releases, int *x, int *y); 49 | int CountButtonReleases (int button, int *releases, int *x, int *y); 50 | void MouseWindow (int x1, int y1, int x2, int y2); 51 | void DefineTextMouseCursor (int type, int andmask, int ormask); 52 | void GetMouseMoved (int *distx, int *disty); 53 | void SetLightPenOn (void); 54 | void SetLightPenOff (void); 55 | void SetMickey (int hm, int vm); 56 | void CloseMouse (void); 57 | 58 | /* Himouse.c -- Only in defrag */ 59 | 60 | #ifndef HI_TECH_C 61 | 62 | void ClearMouse (void); 63 | int MousePressed (int button); 64 | int MouseReleased (int button); 65 | int PressedInRange (int x1, int y1, int x2, int y2); 66 | int ReleasedInRange (int x1, int y1, int x2, int y2); 67 | int AnyButtonPressed (void); 68 | 69 | int GetPressedX (); 70 | int GetPressedY (); 71 | int GetReleasedX (); 72 | int GetReleasedY (); 73 | 74 | void LockMouse (); 75 | void UnLockMouse (); 76 | 77 | #endif 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /nls/DISKCOPY.EN: -------------------------------------------------------------------------------- 1 | #### reserved to condition for example yes, no, quit #### 2 | 0.0:Y 3 | 0.1:N 4 | #### Space reserved to file diskcopy.c #### 5 | 1.0:Invalid drive specification or non removable media. 6 | 1.1:Error reading configuration file. 7 | 1.2:Invalid switch: 8 | 1.3:Too many parameters: 9 | 1.4:File is write protected! 10 | 1.5:copied to 11 | 1.6:File not found: 12 | 1.7:File already exists! 13 | 1.8:Insert SOURCE diskette into drive 14 | 1.9:Press any key to continue . . . 15 | 1.10:Disk not ready! 16 | 1.11:Unable to open image file. 17 | 1.12:Not enough disk space on target drive! 18 | 1.13:Error accessing image file: 19 | 1.14:Insufficient memory for disk copy. 20 | 1.15:Using 21 | 1.16:temporary file. 22 | 1.17:Reading SOURCE diskette . . . 23 | 1.18:Media error reading from sector 24 | 1.19:Writing to image file. 25 | 1.20:Unsuspected memory error. 26 | 1.21:Insert TARGET diskette into drive 27 | 1.22:Diskette does not have the same capacity as the original. 28 | 1.23:Put a diskette with the right capacity in drive 29 | 1.24:or press CTRL-C to cancel. 30 | 1.25:Writing to TARGET diskette in drive . . . 31 | 1.26:Reading from image file. 32 | 1.27:Media error writing to sector 33 | 1.28:Do you want another copy of this 34 | 1.29:image file (Y/N)? 35 | 1.30:disk (Y/N)? 36 | 1.31:Copy another disk (Y/N)? 37 | 1.32:Can not copy image file. 38 | 1.33:Problem reading image file. 39 | 1.34:Creating image file . . . 40 | 1.35:Writing image file . . . 41 | 1.36:Problem writing image file. 42 | 1.37:Compare error on sector 43 | 1.38:Verifying . . . 44 | 1.39:Using verification 45 | 1.40:Volume serial number is 46 | 1.41:Sector 0 unwritable! Write protected? 47 | #### text is "Warning: options % doesn't do anything!" #### 48 | 2.0:Warning: option 49 | 2.1:doesn't do anything! 50 | #### text is "Problem copying % to %" #### 51 | 3.0:Problem copying 52 | 3.1:to 53 | #### text is "Copying % clusters, % sectors per cluster, #### 54 | #### % bytes per sector.\n Drive size is % bytes" #### 55 | 4.0:Copying 56 | 4.1:clusters 57 | 4.2:sectors per cluster 58 | 4.3:bytes per sector. 59 | 4.4:Relevant drive size is 60 | 4.5:bytes. 61 | 5.0:buffer of 62 | 5.1:bytes. 63 | #### Space reserved to file parser.c #### 64 | #### Text is "Syntax error on line % in #### 65 | #### configuration file" #### 66 | 6.0:Syntax error on line 67 | 6.1:in configuration file 68 | 6.2:Semantic error in configuration file 69 | 6.3:do not enter more than one '=' 70 | #### Don't translate the following uppercase words! #### 71 | 6.4:Please enter YES or NO 72 | 6.5:Please enter NEVER or ALWAYS 73 | 6.6:please enter RECOVERY or NORMAL 74 | 6.7:please enter FAST or FULL 75 | 6.8:please enter UPDATE or LEAVE 76 | #### Space reserver to file recovery.c #### 77 | 6.10:Media error reading from disk, rescanning... 78 | 6.11:Unreadable sector at position 79 | #### Space reserved to file tdrvcpy.c #### 80 | 7.0:Put source diskette in drive 81 | 7.1:Put destination diskette in drive 82 | 7.2:Press any key to continue... 83 | 7.3:Invalid src drive specification or non removable media. 84 | 7.4:Invalid dst drive specification or non removable media. 85 | 7.5:Diskette does not have the same capacity as the original. 86 | 7.6:Insuficient memory error. 87 | 7.7:Media error reading from sector 88 | 7.8:Media error writing to sector 89 | 7.9:Do you want to copy two other diskettes (y/n)? 90 | 8.0:Put a diskette with the right capacity in drive 91 | 8.1:or 92 | 8.2:or press CTRL-C to cancel. 93 | 9.0:Copying 94 | 9.1:clusters 95 | 9.2:sectors per cluster 96 | 9.3:bytes per sector. 97 | 9.4:Relevant drive size is 98 | 9.5:bytes. 99 | 9.6:Copying . . . 100 | 9.7:Verifying . . . 101 | ### Place reserved for the strings in the help screen ### 102 | 9.50:Copy one diskette or image file to another diskette or image file. 103 | 9.51:by 104 | 9.52:source 105 | 9.53:destination 106 | 9.54:source: drive or image file to copy from. 107 | 9.55:destination: drive or image file to copy to. 108 | 9.56:give an audible warning for user action. 109 | 9.57:verify reads and writes. 110 | 9.58:only use memory for disk copy. 111 | 9.59:show memory usage (informative). 112 | 9.60:overwrite destination, if it already exists (in case of an image file). 113 | 9.61:always automaticaly exit. 114 | 9.62:assume disk already in drive. 115 | 9.63:go into disk error recovery mode. 116 | 9.64:perform fast diskcopy (only copy filled sectors). 117 | 9.65:Remarks: a minus sign after an option disables the option. 118 | 9.66: You may specify the same drive for source and destination. 119 | 9.67:no-op included for MS-DOS compatibility. 120 | 9.40:don't ask target disk if copying image file to same disk. 121 | -------------------------------------------------------------------------------- /nls/diskcopy.FI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/nls/diskcopy.FI -------------------------------------------------------------------------------- /nls/diskcopy.de: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/nls/diskcopy.de -------------------------------------------------------------------------------- /nls/diskcopy.nl: -------------------------------------------------------------------------------- 1 | #### gereserveerd voor conditie bijvoorbeeld ja, nee, sluiten #### 2 | 0.0:J 3 | 0.1:N 4 | #### Plaats gereserveerd voor bestand diskcopy.c #### 5 | 1.0:Ongeldige station specificatie of niet geldig medium. 6 | 1.1:Fout bij het lezen van het configuratie bestand. 7 | 1.2:Ongeldige optie: 8 | 1.3:Te veel parameters: 9 | 1.4:Bestand is tegen schrijven beveiligd! 10 | 1.5:Gekopieerd naar 11 | 1.6:Bestand niet gevonden: 12 | 1.7:Bestand bestaat reeds! 13 | 1.8:Steek de BRON diskette in station 14 | 1.9:Druk een toets om verder te gaan . . . 15 | 1.10:Station niet klaar! 16 | 1.11:Kan het afbeeldingsbestand niet openen. 17 | 1.12:Niet genoeg schijf ruimte op de doel diskette! 18 | 1.13:Fout bij het benaderen van het afbeeldingsbestand: 19 | 1.14:Niet genoeg geheugen voor het kopieren van de de diskette. 20 | 1.15:Gebruikt 21 | 1.16:tijdelijk bestand. 22 | 1.17:Lezen van de BRON diskette . . . 23 | 1.18:Media fout bij het lezen van sector 24 | 1.19:Schrijven naar afbeeldingsbestand. 25 | 1.20:Onverwachte geheugen fout. 26 | 1.21:Steek de DOEL diskette in station 27 | 1.22:Diskette heeft niet dezelfde capaciteit als het origineel. 28 | 1.23:Steek een diskette met de juiste capaciteit in schijf station 29 | 1.24:of druk CTRL-C om af te breken. 30 | 1.25:Schrijven naar DOEL diskette in station . . . 31 | 1.26:Lezen van afbeeldingsbestand. 32 | 1.27:Media fout bij het schrijven naar sector 33 | 1.28:Wilt u een andere kopie van 34 | 1.29:dit afbeeldingsbestand (J/N)? 35 | 1.30:deze diskette (J/N)? 36 | 1.31:Kopieer een andere diskette (J/N)? 37 | 1.32:Kan afbeeldingsbestand niet kopieren. 38 | 1.33:Probleem bij het lezen van het afbeeldingsbestand. 39 | 1.34:Bezig met het aanmaken van het afbeeldingsbestand . . . 40 | 1.35:Schrijven van afbeeldingsbestand . . . 41 | 1.36:Probleem bij het schrijven van het afbeeldingsbestand. 42 | 1.37:Vergelijkingsfout bij sector 43 | 1.38:Vergelijken . . . 44 | 1.39:Met verificatie 45 | 1.40:Het volumenummer is 46 | 1.41:Sector 0 onschrijfbaar! Tegen schrijven beschermd? 47 | #### tekst is "Waarschuwing: optie % doet niets!" #### 48 | 2.0:Waarschuwing: optie 49 | 2.1:doet niets! 50 | #### tekst is "Probleem met het kopieren van % naar %" #### 51 | 3.0:Probleem met het kopieren van 52 | 3.1:naar 53 | #### tekst is "Bezig met het kopieren van % clusters, % sectoren per cluster, #### 54 | #### % bytes per sector.\n Relevante schijf ruimte is % bytes" #### 55 | 4.0:Kopieren van 56 | 4.1:clusters 57 | 4.2:sectoren per cluster 58 | 4.3:bytes per sector 59 | 4.4:Relevante schijf ruimte is 60 | 4.5:bytes 61 | 5.0:buffer van 62 | 5.1:bytes 63 | #### Plaats gereserveerd voor bestand parser.c #### 64 | #### Tekst is "Syntaxis fout op lijn % in #### 65 | #### configuratie bestand" #### 66 | 6.0:Syntaxis fout op lijn 67 | 6.1:in configuratie bestand. 68 | 6.2:Semantische fout 69 | 6.3:Geef niet meer dan een '='in 70 | 6.4:Gelieve YES of NO in te geven 71 | 6.5:Gelieve NEVER of ALWAYS in te geven 72 | 6.6:Gelieve RECOVERY of NORMAL in te geven 73 | 6.7:Gelieve FAST of FULL in te geven 74 | 6.8:Gelieve UPDATE of LEAVE int te geven 75 | #### Plaats gereserveerd voor bestand recovery.c #### 76 | 6.10:Media fout bij het lezen van schijf, opnieuw... 77 | 6.11:Onleesbare sector op positie 78 | #### Plaats gereserveerd voor bestand tdrvcpy.c #### 79 | 7.0:Plaats bron diskette in station 80 | 7.1:Plaats doel diskette in station 81 | 7.2:Druk een toets om verder te gaan... 82 | 7.3:Ongeldige bron schijf specificatie of niet verwijderbaar medium. 83 | 7.4:Ongeldige doel schijf specificatie of niet verwijderbaar medium. 84 | 7.5:Diskette heeft niet dezelfde capaciteit als het origineel. 85 | 7.6:Niet genoeg geheugen. 86 | 7.7:Medium fout bij het lezen van sector 87 | 7.8:Medium fout bij het schrijven naar sector 88 | 7.9:Wilt u twee andere diskettes kopieren(j/n)? 89 | 8.0:Plaats een diskette met de juiste capaciteit in schijf 90 | 8.1:of 91 | 8.2:of druk CTRL-C om af te breken. 92 | 9.0:Bezig met het kopieren van 93 | 9.1:clusters 94 | 9.2:sectoren per cluster 95 | 9.3:bytes per sector. 96 | 9.4:Relevante schijf ruimte is 97 | 9.5:bytes 98 | 9.6:Kopieren . . . 99 | 9.7:Verifieren . . . 100 | ### Plaats gereserveerd voor de help screen ### 101 | 9.50:Kopieer een diskette of afbeeldingsbestand naar een andere. 102 | 9.51:door 103 | 9.52:bron 104 | 9.53:doel 105 | 9.54:bron: schijf of afbeeldingsbestand om van te kopieren. 106 | 9.55:doel: schijf of afbeeldingsbestand om naar te kopieren. 107 | 9.56:geeft een hoorbare waarschuwing voor gebruikers actie. 108 | 9.57:verifieer lezen en schrijven. 109 | 9.58:gebruik alleen geheugen bij het kopieren. 110 | 9.59:toon geheugen gebruik (informatief). 111 | 9.60:overschrijf doel, als het reeds bestaat (voor een afbeeldingbestand). 112 | 9.61:altijd automatisch eindigen. 113 | 9.62:neem aan dat de diskette reeds in het station steekt. 114 | 9.63:ga in de schijf fout herstellings modus. 115 | 9.64:doe een snelle diskcopy (alleen gevulde sectoren kopieren). 116 | 9.65:Opmerkingen: een minus teken na een optie schakelt de optie uit. 117 | 9.66: u mag dezelfde schijf specificeren voor bron en doel. 118 | 9.67:no-op toegevoegd voor MS-DOS compatibiliteit. 119 | 9.40:vraag niet naar diskette bij creeeren van een bestand op die diskette. 120 | -------------------------------------------------------------------------------- /nls/diskcopy.tr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FDOS/diskcopy/e0178cfb1bbf23844bbe5258bdf65d9d5b2e09b0/nls/diskcopy.tr -------------------------------------------------------------------------------- /nlsaspct.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef INTERNATIONALIZATION_ASPECT_H_ 27 | #define INTERNATIONALIZATION_ASPECT_H_ 28 | 29 | /* 30 | ** Poor man's aspect oriented implementation of the internationalization 31 | ** aspect on diskcopy. 32 | ** 33 | ** Crosscuts are explicitelly named in the component code. I.e. no full 34 | ** seperation of concerns. 35 | */ 36 | 37 | #include "cats\catgets.h" 38 | 39 | #define DISKCOPY_NLS_FILE_BASE "diskcopy" 40 | 41 | /* 42 | ** Aspect definition to define the data used in the implementation 43 | ** of the aspect. 44 | */ 45 | #define CROSSCUT_NLS_DATA \ 46 | char *Cade[5]; \ 47 | nl_catd catd; \ 48 | \ 49 | char CatYES='Y'; /* Default values for YES and NO, */ \ 50 | char CatNO ='N'; /* can be overwritten */ 51 | 52 | /* 53 | ** This definition imports the NLS data objects in the 54 | ** current name space. 55 | */ 56 | #define CROSSCUT_NLS_DATA_IMPORT \ 57 | extern char* Cade[]; \ 58 | extern nl_catd catd; \ 59 | \ 60 | extern char CatYES; \ 61 | extern char CatNO; 62 | 63 | /* 64 | ** This definition opens the catalog and sets catYES and catNO, 65 | ** i.e. the NLS values for 'Y' and 'N'. 66 | */ 67 | #define CROSSCUT_NLS_OPEN \ 68 | { \ 69 | /* Try opening NLS catalog*/ \ 70 | catd = catopen (DISKCOPY_NLS_FILE_BASE, 1); \ 71 | \ 72 | /* Get the definition for YES and NO chars */ \ 73 | Cade[0] = catgets (catd, 0, 0, "Y"); \ 74 | CatYES=*(char *)Cade[0]; \ 75 | Cade[0] = catgets (catd, 0, 1, "N"); \ 76 | CatNO =*(char *)Cade[0]; \ 77 | } 78 | 79 | /* 80 | ** This definition closes the catalog. 81 | */ 82 | #define CROSSCUT_NLS_CLOSE \ 83 | { \ 84 | /* Close the catalog */ \ 85 | catclose(catd); \ 86 | } 87 | 88 | 89 | /* 90 | ** This (generic) aspect gets the indicated message from the catalog 91 | ** and writes it on the screen. 92 | */ 93 | #define NLS_PRINTSTRING(setnum, msgnum, message) \ 94 | { \ 95 | Cade[0] = catgets (catd, setnum, msgnum, message); \ 96 | printf("%s", Cade[0]); \ 97 | } 98 | 99 | /* 100 | ** This (generic) aspect gets the indicated message from the catalog 101 | ** and writes it on the screen, followed by a newline. 102 | */ 103 | #define NLS_PUTSTRING(setnum, msgnum, message) \ 104 | { \ 105 | Cade[0] = catgets (catd, setnum, msgnum, message); \ 106 | printf("%s", Cade[0]); \ 107 | puts(""); \ 108 | } 109 | 110 | /* 111 | ** This definition returns the indicated string. 112 | */ 113 | #define NLS_STRING(setnum, msgnum, message) \ 114 | catgets(catd, setnum, msgnum, message) 115 | 116 | 117 | /* 118 | ** These definitions test wether the char is the NLS char for YES or NO. 119 | */ 120 | 121 | #define NLS_TEST_YES_NO(x) \ 122 | ((x == CatYES) || (x == CatNO)) 123 | 124 | #define NLS_TEST_YES(x) \ 125 | (x == CatYES) 126 | 127 | #define NLS_TEST_NO(x) \ 128 | (x == CatNO) 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef PARSER_H_ 27 | #define PARSER_H_ 28 | 29 | typedef int TOKEN; 30 | 31 | /* Parser input structure. */ 32 | 33 | struct LValueArray 34 | { 35 | TOKEN token; 36 | void (*func) (TOKEN rvalue); 37 | }; 38 | 39 | struct HeaderArray 40 | { 41 | int amount; 42 | TOKEN header; 43 | struct LValueArray *lvalues; 44 | }; 45 | 46 | /* Parser output structure. */ 47 | 48 | struct IniParserStruct 49 | { 50 | 51 | /* MEMORY */ 52 | int UseEMS; /* Use of EMS granted. */ 53 | int UseXMS; /* Use of XMS granted. */ 54 | int UseSWAP; /* Use of SWAP granted. */ 55 | 56 | /* OPTIONS */ 57 | int audible; /* Give an audible warning. */ 58 | int verify; /* Verify writes. */ 59 | int informative; /* Give information on memory use. */ 60 | int overwrite; /* Overwrite destination. */ 61 | int autoexit; /* Always automatically exit. */ 62 | int askdisk; /* Ask disk. */ 63 | int asktdisk; /* Ask target disk. */ 64 | int mode; /* Mode that diskcopy is in. */ 65 | int speed; /* Copy speed: fast or full. */ 66 | int serialnumber; /* Wether to update the serial number */ 67 | 68 | /* GENERATION */ 69 | int MakeDAT; /* Wether or not to keep a compiled 70 | DAT file. */ 71 | }; 72 | 73 | /* Tokens. */ 74 | #define TknNONE -1 /* Invalid input. */ 75 | #define TknDONE 0 /* End of buffer reached. */ 76 | 77 | #define TknSPACE 1 /* white space */ 78 | #define TknASSIGN 2 /* = */ 79 | #define TknYES 3 /* yes */ 80 | #define TknNO 4 /* no */ 81 | #define TknALWAYS 5 /* always */ 82 | #define TknNEVER 6 /* never */ 83 | 84 | 85 | #define TknMEMORYHEADER 7 /* [- MEMORY -] */ 86 | #define TknDISK 8 /* DISK/SWAP */ 87 | #define TknEMS 9 /* EMS */ 88 | #define TknXMS 10 /* XMS */ 89 | 90 | #define TknOPTIONHEADER 11 /* [- OPTIONS -] */ 91 | #define TknAUDIBLE 12 /* audible */ 92 | #define TknVERIFY 13 /* verify */ 93 | #define TknINFORMATIVE 14 /* informative */ 94 | #define TknOVERWRITE 15 /* overwrite */ 95 | #define TknAUTOEXIT 16 /* autoexit */ 96 | #define TknMODE 17 /* mode */ 97 | #define TknASKDISK 18 /* ask disk */ 98 | #define TknASKTARGET 19 /* ask target */ 99 | #define TknSERIALNUMBER 20 /* serial number */ 100 | #define TknUPDATE 21 /* update */ 101 | #define TknLEAVE 22 /* leave */ 102 | 103 | #define TknRECOVERY 23 /* recovery */ 104 | #define TknNORMAL 24 /* normal */ 105 | 106 | #define TknRETURN 25 /* Return */ 107 | 108 | #define TknGENERATEHEADER 26 /* [- GENERATE -] */ 109 | #define TknUSEDATFILE 27 /* usedatfile */ 110 | 111 | #define TknFAST 28 112 | #define TknFULL 29 113 | #define TknSPEED 30 114 | 115 | #define TknOPENBLOCK 31 116 | #define TknCLOSEBLOCK 32 117 | 118 | #define PARSERSUCCESS 1 119 | 120 | #define YES 1 121 | #define NO 0 122 | 123 | #define ALWAYS 1 124 | #define NEVER 0 125 | 126 | #define RECOVERY 1 127 | #define NORMAL 0 128 | 129 | #define UPDATE 1 130 | #define LEAVE 0 131 | 132 | int ParseIniFile (char *filename); 133 | struct IniParserStruct *GetParsedData (void); 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /recovery.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worlonline.be 23 | 24 | module: recovery.c : routine for handling recovery mode. 25 | 26 | */ 27 | 28 | #include "diskcopy.h" 29 | #include "drive.h" 30 | #include "nlsaspct.h" 31 | 32 | #include 33 | #include 34 | 35 | CROSSCUT_NLS_DATA_IMPORT 36 | 37 | /* 38 | ** Reads sectors one by one retrying on every failed sector. 39 | ** 40 | ** Note: a) doesn't return a error status, because it is supposed to never 41 | ** fail. 42 | ** b) this routine is written in order to do be able to do 43 | ** error recovery. 44 | */ 45 | 46 | #define RETRIES 3 /* Retry three times before failing. */ 47 | 48 | void 49 | ReadSectors (int drive, int nsects, int lsect, void *buffer, 50 | int bytespersector) 51 | { 52 | int i, j, success; 53 | char* bptr; 54 | 55 | if (absread (drive, nsects, lsect, buffer) == 0) 56 | return; /* SUCCESS */ 57 | 58 | 59 | puts (""); 60 | NLS_PUTSTRING (6, 10, "Media error reading from disk, rescanning..."); 61 | 62 | for (i = 0; i < nsects; i++) 63 | { 64 | success = FALSE; 65 | 66 | if (absread (drive, 1, lsect, buffer) == -1) 67 | { 68 | for (j = 1; j < RETRIES; j++) /* already tried once. */ 69 | { 70 | if (absread (drive, 1, lsect, buffer) == 0) 71 | { 72 | success = TRUE; 73 | break; 74 | } 75 | } 76 | 77 | if (!success) 78 | { 79 | NLS_PRINTSTRING (6, 11, "Unreadable sector at position"); 80 | printf (" %d.\n", lsect); 81 | } 82 | } 83 | 84 | lsect++; 85 | bptr = (char *) buffer; 86 | bptr += bytespersector; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /scanner.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef SCANNER_H_ 27 | #define SCANNER_H_ 28 | 29 | /* Return codes. */ 30 | #define SCANFILENOTFOUND 0 31 | #define SCANFILEERROR -1 32 | #define SCANSUCCESS 1 33 | 34 | /* ini file name. */ 35 | #define INIFILENAME "diskcopy.ini" 36 | 37 | int OpenScannerFile (char *filename); 38 | void CloseScanner (void); 39 | void RestartScanning (char *filename); 40 | TOKEN GetNextToken (void); 41 | char *ScannerString (void); 42 | TOKEN PeekToken (void); 43 | int GetScannerLine (void); 44 | 45 | char *GetIniDir (char *filename, char *buffer); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /serialnm.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "nlsaspct.h" 32 | #include "boot.h" 33 | 34 | #ifdef HI_TECH_C 35 | #include "pacc\timdat.h" 36 | #endif 37 | 38 | CROSSCUT_NLS_DATA_IMPORT 39 | 40 | static unsigned char SerialNumber[4]; 41 | 42 | void 43 | ClearDiskSerialNumber (char *buf) 44 | { 45 | struct BootSectorStruct *boot = (struct BootSectorStruct *) buf; 46 | 47 | memset (boot->fs.spc1216.SerialNumber, '\0', 4); 48 | } 49 | 50 | void 51 | UpdateDiskSerialNumber (char *buf) 52 | { 53 | struct time theTime; 54 | struct date theDate; 55 | 56 | struct BootSectorStruct *boot = (struct BootSectorStruct *) buf; 57 | unsigned first, second; 58 | 59 | gettime (&theTime); 60 | getdate (&theDate); 61 | 62 | first = ((theTime.ti_hour << 8) + theTime.ti_min) + 63 | (theDate.da_year + 1980); 64 | 65 | second = ((theTime.ti_sec << 8) + theTime.ti_hund) + 66 | ((theDate.da_mon << 8) + theDate.da_day); 67 | 68 | memcpy (boot->fs.spc1216.SerialNumber, &first, 2); 69 | memcpy (((char *) boot->fs.spc1216.SerialNumber) + 2, &second, 2); 70 | 71 | memcpy (SerialNumber, boot->fs.spc1216.SerialNumber, 4); 72 | } 73 | 74 | void 75 | PrintDiskSerialNumber (void) 76 | { 77 | int i; 78 | 79 | NLS_PRINTSTRING (1, 40, "Volume serial number is"); 80 | printf (" "); 81 | 82 | for (i = 3; i >= 0; i--) 83 | { 84 | if (i == 1) 85 | printf ("-"); 86 | printf ("%.2X", SerialNumber[i]); 87 | } 88 | } -------------------------------------------------------------------------------- /serialnm.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef SERIALNUM_H_ 27 | #define SERIALNUM_H_ 28 | 29 | void UpdateDiskSerialNumber (char *buf); 30 | void PrintDiskSerialNumber (void); 31 | void ClearDiskSerialNumber (char *buf); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /simplcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worlonline.be 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | #ifndef HI_TECH_C 30 | #include /* for access */ 31 | #else 32 | #include 33 | #endif 34 | 35 | #include "drive.h" 36 | #include "diskcopy.h" 37 | 38 | #define FAILSAFE 39 | 40 | static int FastCopy (FILE* sfptr, FILE* tfptr, unsigned bufsize, void* buf) 41 | { 42 | int i; 43 | long flen; 44 | 45 | if (fseek(sfptr, 0, SEEK_END)) 46 | return FALSE; 47 | 48 | if ((flen = ftell(sfptr)) == -1) 49 | return FALSE; 50 | 51 | if (fseek(sfptr, 0, SEEK_SET)) 52 | return FALSE; 53 | 54 | for (i = 0; i < flen / bufsize; i++) 55 | { 56 | if (fread(buf, 1, bufsize, sfptr) != bufsize) 57 | return FALSE; 58 | 59 | if (fwrite(buf, 1, bufsize, tfptr) != bufsize) 60 | return FALSE; 61 | } 62 | 63 | if (fread(buf, 1, flen % bufsize, sfptr) != flen % bufsize) 64 | return FALSE; 65 | if (fwrite(buf, 1, flen % bufsize, tfptr) != flen % bufsize) 66 | return FALSE; 67 | 68 | return TRUE; 69 | } 70 | 71 | #ifdef FAILSAFE 72 | 73 | static int SlowCopy(FILE* sfptr, FILE* tfptr) 74 | { 75 | int c; 76 | 77 | while ((c = fgetc (sfptr)) != EOF) 78 | if (fputc (c, tfptr) == EOF) 79 | return FALSE; 80 | 81 | return TRUE; 82 | } 83 | 84 | #endif 85 | 86 | int 87 | CopyFile (char *source, char *destination) 88 | { 89 | FILE *sfptr, *tfptr; 90 | void* buf; 91 | unsigned memsize; 92 | int result; 93 | 94 | /* Look if the destination does not already exists. */ 95 | #ifndef HI_TECH_C 96 | if (access (destination, EXISTS) == 0) 97 | return FALSE; 98 | #else 99 | if (ffirst(destination) != NULL) 100 | return FALSE; 101 | #endif 102 | 103 | sfptr = fopen (source, "rb"); 104 | if (sfptr == NULL) 105 | return FALSE; 106 | 107 | tfptr = fopen (destination, "wb"); 108 | if (tfptr == NULL) 109 | { 110 | fclose (sfptr); 111 | return FALSE; 112 | } 113 | 114 | memsize = coreleft(); 115 | buf = malloc(memsize); 116 | 117 | #ifdef FAILSAFE 118 | if (!buf) 119 | result = SlowCopy(sfptr, tfptr); 120 | else 121 | { 122 | #endif 123 | result = FastCopy(sfptr, tfptr, memsize, buf); 124 | free(buf); 125 | #ifdef FAILSAFE 126 | if (!result) 127 | { 128 | fseek(sfptr, 0, SEEK_SET); 129 | fseek(tfptr, 0, SEEK_SET); 130 | result = SlowCopy(sfptr, tfptr); 131 | } 132 | } 133 | #endif 134 | 135 | fclose (sfptr); 136 | fclose (tfptr); 137 | 138 | if (result) 139 | return TRUE; 140 | else 141 | { 142 | unlink(destination); 143 | return FALSE; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /simplcpy.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef SIMPLECOPY_H_ 27 | #define SIMPLECOPY_H_ 28 | 29 | int CopyFile (char *source, char *destination); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /smdskcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MS-DOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001 Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | module: smdskcpy.c - (small drive copy) contains routines to read and 25 | write a small image file to the same disk as where 26 | the file is stored. 27 | 28 | */ 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifndef HI_TECH_C 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #endif 43 | 44 | #include "memtypes.h" 45 | #include "drive.h" 46 | #include "waitfinp.h" 47 | #include "critical.h" 48 | #include "nlsaspct.h" 49 | #include "diskcopy.h" 50 | 51 | CROSSCUT_NLS_DATA_IMPORT 52 | 53 | int 54 | ReadFileIntoMemory (char *file, char *buffer, unsigned bsize) 55 | { 56 | int handle; 57 | unsigned long fsize, i; 58 | 59 | handle = open (file, O_RDONLY | O_BINARY); 60 | if (handle == -1) 61 | return FALSE; 62 | 63 | fsize = filelength (handle); 64 | if ((fsize % bsize) != 0) 65 | { 66 | close (handle); 67 | return FALSE; 68 | } 69 | 70 | for (i = 0; i < fsize / bsize; i++) 71 | { 72 | if ((read (handle, buffer, bsize) != bsize) || 73 | (!WriteMemoryBlock (buffer, bsize))) 74 | { 75 | close (handle); 76 | return FALSE; 77 | } 78 | } 79 | 80 | 81 | close (handle); 82 | return TRUE; 83 | } 84 | 85 | int 86 | WriteFileFromMemory (char *file, char *buffer, unsigned bsize, 87 | unsigned long floppysize, int askdisk, int fallthrough, 88 | int overwrite) 89 | { 90 | unsigned long i; 91 | int criterr = 0, wrhandle; 92 | 93 | if (askdisk) 94 | { 95 | puts ("\n"); 96 | NLS_PUTSTRING (1, 21, "Insert TARGET diskette into drive"); 97 | puts (""); 98 | NLS_PRINTSTRING (1, 9, "Press any key to continue . . ."); 99 | WaitForInput (); 100 | } 101 | 102 | /* Check disk capacity is the same as that of the original 103 | diskette. */ 104 | for (;;) 105 | { 106 | if (!DiskLargeEnough (file, floppysize) || 107 | ((criterr = CriticalErrorOccured ()) != 0)) 108 | { 109 | puts (""); 110 | if (criterr) 111 | { 112 | NLS_PUTSTRING (1, 10, "Disk not ready!"); 113 | } 114 | else 115 | NLS_PUTSTRING (1, 12, "Not enough disk space on target drive!"); 116 | 117 | if (fallthrough) 118 | return FALSE; 119 | 120 | puts (""); 121 | NLS_PRINTSTRING (1, 23, "Put a diskette with the right capacity in drive"); 122 | printf (" %c:,\n", GetDiskFromPathName (file)); 123 | NLS_PUTSTRING (1, 24, "or press CTRL-C to cancel."); 124 | WaitForInput (); /* When the user presses CTRL-C this function does not return */ 125 | } 126 | else 127 | break; 128 | } 129 | 130 | if (access (file, EXISTS) == 0) 131 | { 132 | if (overwrite) 133 | { 134 | if (remove (file) == -1) 135 | { 136 | puts (""); 137 | NLS_PUTSTRING (1, 4, "File is write protected!"); 138 | return FALSE; 139 | } 140 | } 141 | else 142 | { 143 | puts ("\n"); 144 | NLS_PUTSTRING (1, 7, "File already exists!"); 145 | return FALSE; 146 | } 147 | } 148 | 149 | wrhandle = open (file, O_WRONLY | O_BINARY | O_CREAT); 150 | 151 | if (wrhandle == -1) 152 | return FALSE; 153 | 154 | for (i = 0; i < floppysize / bsize; i++) 155 | { 156 | if (!ReadMemoryBlock (buffer, bsize) || 157 | (write (wrhandle, buffer, bsize) != bsize)) 158 | { 159 | close (wrhandle); 160 | if (access (file, EXISTS) == 0) 161 | { 162 | chmod (file, S_IWRITE); 163 | remove (file); 164 | } 165 | return FALSE; 166 | } 167 | } 168 | 169 | close (wrhandle); 170 | chmod (file, S_IWRITE); 171 | return TRUE; 172 | } 173 | -------------------------------------------------------------------------------- /smdskcpy.h: -------------------------------------------------------------------------------- 1 | #ifndef SMQLL_DISKCOPY_H_ 2 | #define SMALL_DISKCOPY_H_ 3 | 4 | int WriteFileFromMemory (char *file, char *buffer, unsigned bsize, 5 | unsigned long floppysize, int askdisk, 6 | int fallthrough, int overwrite); 7 | int ReadFileIntoMemory (char *file, char *buffer, unsigned bsize); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /tdrvcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worlonline.be 23 | 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "diskcopy.h" 35 | #include "tdrvcpy.h" 36 | #include "memtypes.h" 37 | #include "waitfinp.h" 38 | #include "drive.h" 39 | #include "fastcopy.h" 40 | #include "nlsaspct.h" 41 | #include "parser.h" 42 | #include "serialnm.h" 43 | 44 | CROSSCUT_NLS_DATA_IMPORT 45 | 46 | void 47 | TwoDriveCopy (struct TwoDriveCopyData *pars) 48 | { 49 | int answer, action, success; 50 | struct dfree dskfree; 51 | struct dfree dskfreed; 52 | int sector; 53 | int sectorsperblock; 54 | 55 | unsigned long disksize, endsector, total, FilledDiskSize, FilledTotal; 56 | 57 | answer = CatYES; 58 | 59 | while (answer == CatYES) 60 | { 61 | if (pars->askdisk) 62 | { 63 | puts (""); 64 | NLS_PRINTSTRING (7, 0, "Put source diskette in drive"); 65 | printf (" %c:\n", pars->sourcedrv + 'A'); 66 | NLS_PRINTSTRING (7, 1, "Put destination diskette in drive"); 67 | printf (" %c:\n\n", pars->destdrv + 'A'); 68 | NLS_PRINTSTRING (7, 2, "Press any key to continue..."); 69 | WaitForInput (); 70 | } 71 | 72 | pars->askdisk = TRUE; 73 | 74 | for (;;) 75 | { 76 | if (!DiskReadBootInfo (pars->sourcedrv, &dskfree)) 77 | { 78 | puts (""); 79 | NLS_PUTSTRING (7, 3, "Invalid src drive specification or non removable media."); 80 | exit (INITERROR); 81 | } 82 | 83 | total = dskfree.df_total * dskfree.df_sclus; 84 | disksize = total * dskfree.df_bsec; 85 | 86 | if (disksize == 0) /* If any of the numbers == 0 */ 87 | { 88 | puts (""); 89 | NLS_PUTSTRING (7, 4, "Invalid dst drive specification or non removable media."); 90 | exit (INITERROR); 91 | } 92 | 93 | if (!DiskReadBootInfo (pars->destdrv, &dskfreed)) 94 | { 95 | puts (""); 96 | NLS_PUTSTRING (7, 4, "Invalid dst drive specification or non removable media."); 97 | exit (INITERROR); 98 | } 99 | 100 | if ((dskfree.df_total == dskfreed.df_total) && 101 | (dskfree.df_bsec == dskfreed.df_bsec) && 102 | (dskfree.df_sclus == dskfreed.df_sclus)) 103 | break; 104 | 105 | puts ("\n"); 106 | 107 | NLS_PRINTSTRING (7, 5, "Diskette does not have the same capacity as the original."); 108 | NLS_PRINTSTRING (8, 0, "Put a diskette with the right capacity in drive"); 109 | printf (" %c:", pars->sourcedrv + 'A'); 110 | NLS_PRINTSTRING (8, 1, "or"); 111 | printf ("%c:\n", pars->destdrv + 'A'); 112 | NLS_PUTSTRING (8, 2, "or press CTRL-C to cancel."); 113 | WaitForInput (); 114 | } 115 | 116 | if (pars->copyfast) 117 | { 118 | SetCopySpeed (FAST); 119 | if (!DiskReadFatInfo (pars->sourcedrv)) 120 | SetCopySpeed (FULL); 121 | } 122 | else 123 | SetCopySpeed (FULL); 124 | 125 | FilledDiskSize = GetDiskFilledSize (pars->bufsize); 126 | FilledTotal = (FilledDiskSize / dskfree.df_bsec) / dskfree.df_sclus; 127 | 128 | puts ("\n"); 129 | 130 | NLS_PRINTSTRING (9, 0, "Copying"); 131 | printf (" %d ", FilledTotal); 132 | NLS_PRINTSTRING (9, 1, "clusters"); 133 | printf (", %d ", dskfree.df_sclus); 134 | NLS_PRINTSTRING (9, 2, "sectors per cluster"); 135 | printf (", %d ", dskfree.df_bsec); 136 | NLS_PUTSTRING (9, 3, "bytes per sector."); 137 | NLS_PRINTSTRING (9, 4, "Relevant drive size is"); 138 | printf (" %ld ", FilledDiskSize); 139 | NLS_PUTSTRING (9, 5, "bytes."); 140 | 141 | sectorsperblock = pars->bufsize / BYTESPERSECTOR; 142 | endsector = dskfree.df_total * dskfree.df_sclus; 143 | 144 | for (action = DISKWRITING; 145 | (pars->verify) ? (action <= VERIFICATION) : (action < VERIFICATION); 146 | action++) 147 | { 148 | puts (""); 149 | if (action == DISKWRITING) 150 | { 151 | NLS_PRINTSTRING (9, 6, "Copying . . ."); 152 | } 153 | else 154 | { 155 | NLS_PRINTSTRING (9, 7, "Verifying . . ."); 156 | } 157 | 158 | for (sector = 0; sector < endsector; sector += sectorsperblock) 159 | { 160 | if (IsDiskReadRequired (sector, sectorsperblock)) 161 | { 162 | #ifndef ALL_RECOVERY_MODE 163 | if (pars->recoverymode) 164 | #endif 165 | ReadSectors (pars->sourcedrv, sectorsperblock, sector, pars->cpybuf, 166 | dskfree.df_bsec); 167 | #ifndef ALL_RECOVERY_MODE 168 | else if (absread (pars->sourcedrv, sectorsperblock, sector, pars->cpybuf) != 0) 169 | { 170 | puts (""); 171 | NLS_PRINTSTRING (7, 7, "Media error reading from sector"); 172 | printf (" %d\n", sector); 173 | } 174 | #endif 175 | 176 | #ifdef UPDATE_SERIALNUM 177 | if (sector == 0) 178 | { 179 | if (action == DISKWRITING) 180 | { 181 | if (pars->updateserial == UPDATE) 182 | UpdateDiskSerialNumber (pars->cpybuf); 183 | } 184 | else 185 | { 186 | if (pars->updateserial == UPDATE) 187 | { 188 | ClearDiskSerialNumber (pars->cpybuf); 189 | } 190 | } 191 | } 192 | #endif 193 | 194 | if (action == VERIFICATION) 195 | { 196 | success = absread (pars->destdrv, sectorsperblock, sector, pars->cmpbuf) == 0; 197 | 198 | #ifdef UPDATE_SERIALNUM 199 | if ((sector == 0) && (pars->updateserial == UPDATE)) 200 | ClearDiskSerialNumber (pars->cmpbuf); 201 | #endif 202 | } 203 | else 204 | success = abswrite (pars->destdrv, sectorsperblock, sector, pars 205 | ->cpybuf) == 0; 206 | 207 | 208 | if (!success) 209 | { 210 | puts (""); 211 | NLS_PRINTSTRING (7, 8, "Media error writing to sector"); 212 | printf (" %d\n", sector); 213 | } 214 | 215 | if (action == VERIFICATION) 216 | if (memcmp (pars->cpybuf, pars->cmpbuf, sectorsperblock * BYTESPERSECTOR) != 0) 217 | { 218 | puts (""); 219 | NLS_PRINTSTRING (1, 37, "Compare error on sector"); 220 | printf (" %ld.\n", sector); 221 | } 222 | } 223 | } 224 | } 225 | 226 | if (pars->bel) 227 | Beep (); 228 | 229 | answer = (pars->fallthrough) ? CatNO : CatNO + 1; 230 | if (answer == CatYES) 231 | answer++; 232 | 233 | while (!NLS_TEST_YES_NO (answer)) 234 | { 235 | puts ("\n"); 236 | NLS_PRINTSTRING (7, 9, "Do you want to copy two other diskettes (y/n)?"); 237 | answer = toupper (getch ()); 238 | puts (""); 239 | } 240 | 241 | #ifdef UPDATE_SERIALNUM 242 | if (pars->updateserial == UPDATE) 243 | { 244 | puts (""); 245 | PrintDiskSerialNumber (); 246 | puts (""); 247 | } 248 | #endif 249 | 250 | } 251 | 252 | if (pars->fallthrough) 253 | puts (""); 254 | } 255 | 256 | int 257 | BiosReportsTwoDrives () 258 | { 259 | int configuration = biosequip (); 260 | 261 | if ((configuration & 1) && /* At least one floppy drive. */ 262 | (((configuration >> 6) & 3) >= 1)) 263 | return 1; 264 | else 265 | return 0; 266 | } 267 | -------------------------------------------------------------------------------- /tdrvcpy.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef TDRVCPY_H_ 27 | #define TDRVCPY_H_ 28 | 29 | struct TwoDriveCopyData 30 | { 31 | int sourcedrv; 32 | int destdrv; 33 | char *cpybuf; 34 | char *cmpbuf; 35 | unsigned bufsize; 36 | int bel; 37 | int fallthrough; 38 | int askdisk; 39 | int copyfast; 40 | int verify; 41 | #ifndef ALL_RECOVERY_MODE 42 | int recoverymode; 43 | #endif 44 | #ifdef UPDATE_SERIALNUM 45 | int updateserial; 46 | #endif 47 | }; 48 | 49 | void TwoDriveCopy (struct TwoDriveCopyData *pars); 50 | 51 | int BiosReportsTwoDrives (void); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /waitfinp.c: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MS-DOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, 2001, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worlonline.be 23 | 24 | module: waitfinp.c - routine to wait for the user to press any key 25 | or press any button. 26 | */ 27 | 28 | #include 29 | 30 | #include "mouse.h" 31 | #include "waitfinp.h" 32 | 33 | #define AMOFBUTTONS 3 34 | 35 | /* 36 | ** Returns wether any button was pressed and returns that button or 37 | ** 0 if no button pressed. 38 | */ 39 | 40 | static int 41 | AnyButtonPressed () 42 | { 43 | int presses, x, y; 44 | 45 | return CountButtonPresses (0, &presses, &x, &y) & 7; 46 | } 47 | 48 | /* 49 | ** Clears the keyboard buffer. 50 | */ 51 | void 52 | ClrKbd () 53 | { 54 | while (kbhit ()) 55 | getch (); 56 | } 57 | 58 | /* 59 | ** Clears the mouse from any presses. 60 | */ 61 | static void 62 | ClearMouse () 63 | { 64 | int i, x, y, pressreleases; 65 | 66 | for (i = 0; i < AMOFBUTTONS; i++) 67 | { 68 | CountButtonPresses (i, &pressreleases, &x, &y); 69 | } 70 | } 71 | 72 | /* 73 | ** Real routine: waits until the user has either pressed a key or a button. 74 | */ 75 | 76 | int 77 | WaitForInput () 78 | { 79 | ClearMouse (); 80 | ClrKbd (); 81 | 82 | for (;;) 83 | { 84 | if (AnyButtonPressed ()) /* Mouse button pressed. */ 85 | return -1; 86 | if (kbhit ()) /* Key pressed. */ 87 | return getch (); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /waitfinp.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | #ifndef WAITFINP_H_ 27 | #define WAITFINP_H_ 28 | 29 | void ClrKbd (void); 30 | int WaitForInput (void); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /xms.h: -------------------------------------------------------------------------------- 1 | /* 2 | DISKCOPY.EXE, floppy diskette duplicator similar to MSDOS Diskcopy. 3 | Copyright (C) 1998, Matthew Stanford. 4 | Copyright (C) 1999, 2000, Imre Leber. 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 2 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have recieved a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | 20 | 21 | If you have any questions, comments, suggestions, or fixes please 22 | email me at: imre.leber@worldonline.be 23 | 24 | */ 25 | 26 | /* 27 | ** XMS.H 28 | ** 29 | ** Header file for Extended Memory routines in XMS.ASM. 30 | */ 31 | 32 | #ifndef _XMS_H 33 | #define _XMS_H 34 | 35 | /* initialisation routine. */ 36 | int XMMinit (void); 37 | 38 | /* routines for managing EMB's */ 39 | int XMSinit (void); 40 | int XMSversion (void); 41 | unsigned long XMScoreleft (void); 42 | int XMSfree (unsigned int handle); 43 | long XMSmemcpy (unsigned int desthandle, long destoff, 44 | unsigned int srchandle, long srcoff, long n); 45 | int DOStoXMSmove (unsigned int desthandle, long destoff, 46 | const char *src, unsigned n); 47 | int XMStoDOSmove (char *dest, unsigned int srchandle, long srcoff, unsigned n); 48 | 49 | unsigned int XMSalloc (long size); 50 | 51 | int XMSrealloc (unsigned int handle, long size); 52 | 53 | /* routines for managing the HMA. */ 54 | int HMAalloc (void); 55 | int HMAcoreleft (void); 56 | int HMAfree (void); 57 | 58 | /* routines for managing UMB's. */ 59 | unsigned int UMBalloc (void); 60 | unsigned int GetUMBsize (void); 61 | int UMBfree (unsigned int segment); 62 | 63 | #endif 64 | --------------------------------------------------------------------------------