bool DOS_Rename(char const * const oldname,char const * const newname) { Bit8u driveold;char fullold[DOS_PATHLENGTH]; Bit8u drivenew;char fullnew[DOS_PATHLENGTH]; if (!DOS_MakeName(oldname,fullold,&driveold)) return false; if (!DOS_MakeName(newname,fullnew,&drivenew)) return false; /* No tricks with devices */ if ( (DOS_FindDevice(oldname) != DOS_DEVICES) || (DOS_FindDevice(newname) != DOS_DEVICES) ) { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } /* Must be on the same drive */ if(driveold != drivenew) { DOS_SetError(DOSERR_NOT_SAME_DEVICE); return false; } /*Test if target exists => no access */ Bit16u attr; if(Drives[drivenew]->GetFileAttr(fullnew,&attr)) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } /* Source must exist, check for path ? */ if (!Drives[driveold]->GetFileAttr( fullold, &attr ) ) { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } if (Drives[drivenew]->Rename(fullold,fullnew)) return true; /* If it still fails. which error should we give ? PATH NOT FOUND or EACCESS */ LOG(LOG_FILES,LOG_NORMAL)("Rename fails for %s to %s, no proper errorcode returned.",oldname,newname); DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; }
bool DOS_Rename(char const * const oldname, char const * const newname) { Bit8u driveold; char fullold[DOS_PATHLENGTH]; if (!DOS_MakeName(oldname, fullold, &driveold)) { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } Bit8u drivenew; char fullnew[DOS_PATHLENGTH]; if (!DOS_MakeName(newname, fullnew, &drivenew)) return false; if ((DOS_FindDevice(oldname) != DOS_DEVICES) || (DOS_FindDevice(newname) != DOS_DEVICES)) // No tricks with devices { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } if (driveold != drivenew) // Must be on the same drive { DOS_SetError(DOSERR_NOT_SAME_DEVICE); return false; } Bit16u attr; if (Drives[drivenew]->GetFileAttr(fullnew, &attr)) // Test if target exists => no access { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } if (!Drives[driveold]->GetFileAttr(fullold, &attr )) // Source must exist, check for path ? { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } if (Drives[drivenew]->Rename(fullold, fullnew)) return true; DOS_SetError(DOSERR_FILE_NOT_FOUND); // If it still fails. which error should we give ? PATH NOT FOUND or EACCESS return false; }
bool DOS_UnlinkFile(char const * const name) { char fullname[DOS_PATHLENGTH];Bit8u drive; // An existing device returns an access denied error if (DOS_FindDevice(name) != DOS_DEVICES) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } if (!DOS_MakeName(name,fullname,&drive)) return false; if(Drives[drive]->FileUnlink(fullname)){ return true; } else { DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } }
bool DOS_CreateFile(char const * name,Bit16u attributes,Bit16u * entry,bool fcb) { // Creation of a device is the same as opening it // Tc201 installer if (DOS_FindDevice(name) != DOS_DEVICES) return DOS_OpenFile(name, OPEN_READ, entry, fcb); LOG(LOG_FILES,LOG_NORMAL)("file create attributes %X file %s",attributes,name); char fullname[DOS_PATHLENGTH]; Bit8u drive; DOS_PSP psp(dos.psp()); if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check for a free file handle */ Bit8u handle=DOS_FILES; Bit8u i; for (i=0; i<DOS_FILES; i++) { if (!Files[i]) { handle=i; break; } } if (handle==DOS_FILES) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } /* We have a position in the main table now find one in the psp table */ *entry = fcb?handle:psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } /* Don't allow directories to be created */ if (attributes&DOS_ATTR_DIRECTORY) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } bool foundit=Drives[drive]->FileCreate(&Files[handle],fullname,attributes); if (foundit) { Files[handle]->SetDrive(drive); Files[handle]->AddRef(); if (!fcb) psp.SetFileHandle(*entry,handle); return true; } else { if(!PathExists(name)) DOS_SetError(DOSERR_PATH_NOT_FOUND); else DOS_SetError(DOSERR_FILE_NOT_FOUND); return false; } }
bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { LOG(LOG_FILES,LOG_NORMAL)("file search attributes %X name %s",attr,search); DOS_DTA dta(dos.dta()); Bit8u drive; char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH]; char pattern[DOS_PATHLENGTH]; size_t len = strlen(search); if(len && search[len - 1] == '\\' && !( (len > 2) && (search[len - 2] == ':') && (attr == DOS_ATTR_VOLUME) )) { //Dark Forces installer, but c:\ is allright for volume labels(exclusively set) DOS_SetError(DOSERR_NO_MORE_FILES); return false; } if (!DOS_MakeName(search,fullsearch,&drive)) return false; //Check for devices. FindDevice checks for leading subdir as well bool device = (DOS_FindDevice(search) != DOS_DEVICES); /* Split the search in dir and pattern */ char * find_last; find_last=strrchr(fullsearch,'\\'); if (!find_last) { /*No dir */ strcpy(pattern,fullsearch); dir[0]=0; } else { *find_last=0; strcpy(pattern,find_last+1); strcpy(dir,fullsearch); } dta.SetupSearch(drive,(Bit8u)attr,pattern); if(device) { find_last = strrchr(pattern,'.'); if(find_last) *find_last = 0; //TODO use current date and time dta.SetResult(pattern,0,0,0,DOS_ATTR_DEVICE); LOG(LOG_DOSMISC,LOG_WARN)("finding device %s",pattern); return true; } if (Drives[drive]->FindFirst(dir,dta,fcb_findfirst)) return true; return false; }
bool DOS_CreateFile(char const* name, Bit16u attributes, Bit16u* entry) { if (DOS_FindDevice(name) != DOS_DEVICES) // Creating a device is the same as opening it return DOS_OpenFile(name, OPEN_READWRITE, entry); char fullname[DOS_PATHLENGTH]; Bit8u drive; if (!DOS_MakeName(name, fullname, &drive)) return false; Bit8u handle; for (handle = 0; handle < DOS_FILES; handle++) // Check for a free file handle if (!Files[handle]) break; if (handle == DOS_FILES) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } DOS_PSP psp(dos.psp()); // We have a position in the main table, now find one in the psp table *entry = psp.FindFreeFileEntry(); if (*entry == 0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } if (attributes&DOS_ATTR_DIRECTORY) // Don't allow directories to be created { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } if (Drives[drive]->FileCreate(&Files[handle], fullname, attributes)) { Files[handle]->SetDrive(drive); Files[handle]->AddRef(); psp.SetFileHandle(*entry, handle); return true; } DOS_SetError(PathExists(name) ? DOSERR_FILE_ALREADY_EXISTS : DOSERR_PATH_NOT_FOUND); return false; }
bool DOS_FindFirst(char * search, Bit16u attr, bool fcb_findfirst) { DOS_DTA dta(dos.dta()); size_t len = strlen(search); if (len && search[len - 1] == '\\' && !((len > 2) && (search[len - 2] == ':') && (attr == DOS_ATTR_VOLUME))) { DOS_SetError(DOSERR_NO_MORE_FILES); // Dark Forces installer, but c:\ is allright for volume labels(exclusively set) return false; } char fullsearch[DOS_PATHLENGTH]; Bit8u drive; if (!DOS_MakeName(search, fullsearch, &drive)) return false; char dir[DOS_PATHLENGTH]; // Split the search in dir and pattern char pattern[DOS_PATHLENGTH]; char * find_last = strrchr(fullsearch, '\\'); if (!find_last) // No dir { strcpy(pattern, fullsearch); dir[0] = 0; } else { *find_last = 0; strcpy(pattern, find_last+1); strcpy(dir, fullsearch); } dta.SetupSearch(drive, (Bit8u)attr, pattern); if (bool device = (DOS_FindDevice(search) != DOS_DEVICES)) // Check for devices. FindDevice checks for leading subdir as well { if (!(attr & DOS_ATTR_DEVICE)) return false; if (find_last = strrchr(pattern, '.')) *find_last = 0; dta.SetResult(pattern, 0, 0, 0, DOS_ATTR_DEVICE); // TODO use current date and time return true; } return Drives[drive]->FindFirst(dir, dta, fcb_findfirst); }
bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry,bool fcb) { /* First check for devices */ if (flags>2) LOG(LOG_FILES,LOG_ERROR)("Special file open command %X file %s",flags,name); else LOG(LOG_FILES,LOG_NORMAL)("file open command %X file %s",flags,name); DOS_PSP psp(dos.psp()); Bit16u attr = 0; Bit8u devnum = DOS_FindDevice(name); bool device = (devnum != DOS_DEVICES); if(!device && DOS_GetFileAttr(name,&attr)) { //DON'T ALLOW directories to be openened.(skip test if file is device). if((attr & DOS_ATTR_DIRECTORY) || (attr & DOS_ATTR_VOLUME)) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } } char fullname[DOS_PATHLENGTH]; Bit8u drive; Bit8u i; /* First check if the name is correct */ if (!DOS_MakeName(name,fullname,&drive)) return false; Bit8u handle=255; /* Check for a free file handle */ for (i=0; i<DOS_FILES; i++) { if (!Files[i]) { handle=i; break; } } if (handle==255) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } /* We have a position in the main table now find one in the psp table */ *entry = fcb?handle:psp.FindFreeFileEntry(); if (*entry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } bool exists=false; if (device) { Files[handle]=new DOS_Device(*Devices[devnum]); } else { exists=Drives[drive]->FileOpen(&Files[handle],fullname,flags); if (exists) Files[handle]->SetDrive(drive); } if (exists || device ) { Files[handle]->AddRef(); if (!fcb) psp.SetFileHandle(*entry,handle); return true; } else { //Test if file exists, but opened in read-write mode (and writeprotected) if(((flags&3) != OPEN_READ) && Drives[drive]->FileExists(fullname)) DOS_SetError(DOSERR_ACCESS_DENIED); else { if(!PathExists(name)) DOS_SetError(DOSERR_PATH_NOT_FOUND); else DOS_SetError(DOSERR_FILE_NOT_FOUND); } return false; } }
bool DOS_OpenFile(char const* name, Bit8u flags, Bit16u* entry) { Bit16u attr; Bit8u devnum = DOS_FindDevice(name); // First check for devices bool device = (devnum != DOS_DEVICES); if (device && wpVersion) // WP - clipboard { #pragma warning(suppress: 28159) if (GetTickCount() > wpOpenDevTime + 1000) // Recalibrate after some (1/2 sec) time { wpOpenDevCount = 0; #pragma warning(suppress: 28159) wpOpenDevTime = GetTickCount(); } if ((devnum == 8 || devnum == 17) && !(++wpOpenDevCount&2)) // LPT9/COM9 (1-4 rejected by WP, 9 reserved for Edward Mendelson's macros) { DOS_SetError(PathExists(name) ? DOSERR_FILE_NOT_FOUND : DOSERR_PATH_NOT_FOUND); return false; } } if (!device && DOS_GetFileAttr(name, &attr)) // DON'T allow directories to be openened.(skip test if file is device). if ((attr & DOS_ATTR_DIRECTORY) || (attr & DOS_ATTR_VOLUME)) { DOS_SetError(DOSERR_ACCESS_DENIED); return false; } char fullname[DOS_PATHLENGTH]; Bit8u drive; if (!DOS_MakeName(name, fullname, &drive)) // Check if the name is correct return false; Bit8u handle; for (handle = 0; handle < DOS_FILES; handle++) // Check for a free file handle if (!Files[handle]) break; if (handle == DOS_FILES) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } DOS_PSP psp(dos.psp()); // We have a position in the main table, now find one in the psp table *entry = psp.FindFreeFileEntry(); if (*entry == 0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); return false; } bool exists = false; if (device) Files[handle] = new DOS_Device(*Devices[devnum]); else if (exists = Drives[drive]->FileOpen(&Files[handle], fullname, flags)) Files[handle]->SetDrive(drive); if (exists || device) { Files[handle]->AddRef(); psp.SetFileHandle(*entry, handle); return true; } // Look at his // Test if file exists, but opened in read-write mode (and writeprotected) if (Drives[drive]->FileExists(fullname)) // if (((flags&3) != OPEN_READ) && Drives[drive]->FileExists(fullname)) DOS_SetError(DOSERR_ACCESS_DENIED); else DOS_SetError(PathExists(name) ? DOSERR_FILE_NOT_FOUND : DOSERR_PATH_NOT_FOUND); return false; }