Exemple #1
0
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;
}
Exemple #2
0
bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { 
	DOS_FCB fcb(seg,offset);
	char shortname[DOS_FCBNAME];Bit16u handle;
	fcb.GetName(shortname);

	/* First check if the name is correct */
	Bit8u drive;
	char fullname[DOS_PATHLENGTH];
	if (!DOS_MakeName(shortname,fullname,&drive)) return false;
	
	/* Check, if file is already opened */
	for (Bit8u i=0;i<DOS_FILES;i++) {
		DOS_PSP psp(dos.psp());
		if (Files[i] && Files[i]->IsOpen() && Files[i]->IsName(fullname)) {
			handle = psp.FindEntryByHandle(i);
			if (handle==0xFF) {
				// This shouldnt happen
				LOG(LOG_FILES,LOG_ERROR)("DOS: File %s is opened but has no psp entry.",shortname);
				return false;
			}
			fcb.FileOpen((Bit8u)handle);
			return true;
		}
	}
	
	if (!DOS_OpenFile(shortname,OPEN_READWRITE,&handle)) return false;
	fcb.FileOpen((Bit8u)handle);
	return true;
}
Exemple #3
0
bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset) {
    DOS_FCB fcbold(seg,offset);
    DOS_FCB fcbnew(seg,offset+16);
    if(!fcbold.Valid()) return false;
    char oldname[DOS_FCBNAME];
    char newname[DOS_FCBNAME];
    fcbold.GetName(oldname);
    fcbnew.GetName(newname);

    /* Check, if sourcefile is still open. This was possible in DOS, but modern oses don't like this */
    Bit8u drive;
    char fullname[DOS_PATHLENGTH];
    if (!DOS_MakeName(oldname,fullname,&drive)) return false;

    DOS_PSP psp(dos.psp());
    for (Bit8u i=0; i<DOS_FILES; i++) {
        if (Files[i] && Files[i]->IsOpen() && Files[i]->IsName(fullname)) {
            Bit16u handle = psp.FindEntryByHandle(i);
            //(more than once maybe)
            if (handle == 0xFF) {
                DOS_CloseFile(i,true);
            } else {
                DOS_CloseFile(handle);
            }
        }
    }

    /* Rename the file */
    return DOS_Rename(oldname,newname);
}
Exemple #4
0
bool DOS_RemoveDir(char const * const dir) {
    /* We need to do the test before the removal as can not rely on
     * the host to forbid removal of the current directory.
     * We never change directory. Everything happens in the drives.
     */
    Bit8u drive;
    char fulldir[DOS_PATHLENGTH];
    if (!DOS_MakeName(dir,fulldir,&drive)) return false;
    /* Check if exists */
    if(!Drives[drive]->TestDir(fulldir)) {
        DOS_SetError(DOSERR_PATH_NOT_FOUND);
        return false;
    }
    /* See if it's current directory */
    char currdir[DOS_PATHLENGTH]= { 0 };
    DOS_GetCurrentDir(drive + 1 ,currdir);
    if(strcmp(currdir,fulldir) == 0) {
        DOS_SetError(DOSERR_REMOVE_CURRENT_DIRECTORY);
        return false;
    }

    if(Drives[drive]->RemoveDir(fulldir)) return true;

    /* Failed. We know it exists and it's not the current dir */
    /* Assume non empty */
    DOS_SetError(DOSERR_ACCESS_DENIED);
    return false;
}
Exemple #5
0
bool DOS_MakeDir(char const* const dir)
	{
	Bit8u drive;
	const char *testdir = dir;
	if (*testdir && testdir[1] == ':')
		{
		drive = (*testdir | 0x20)-'a';
		if (drive >= DOS_DRIVES || !Drives[drive])
			{
			DOS_SetError(DOSERR_INVALID_DRIVE);
			return false;
			}
		testdir += 2;
		}
	size_t len = strlen(testdir);
	char fulldir[DOS_PATHLENGTH];
	if (!len || !DOS_MakeName(dir, fulldir, &drive) || (*fulldir && testdir[len-1] == '\\'))
		{
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
		return false;
		}
	if (Drives[drive]->MakeDir(fulldir))
		return true;   
	if (Drives[drive]->TestDir(fulldir))											// Determine reason for failing
		DOS_SetError(DOSERR_ACCESS_DENIED);
	else
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
	return false;
	}
Exemple #6
0
bool DOS_ChangeDir(char const* const dir)
	{
	Bit8u drive;
	const char *testdir = dir;
	if (*testdir && testdir[1] == ':')
		{
		drive = (*dir | 0x20)-'a';
		if (drive >= DOS_DRIVES || !Drives[drive])
			{
			DOS_SetError(DOSERR_INVALID_DRIVE);
			return false;
			}
		testdir += 2;
		}
	size_t len = strlen(testdir);
	char fulldir[DOS_PATHLENGTH];
	if (!len || !DOS_MakeName(dir, fulldir, &drive) || (*fulldir && testdir[len-1] == '\\'))
		{ }
	else if (Drives[drive]->TestDir(fulldir))
		{
		for (int i = 0; fulldir[i]; i++)											// Names in MS-DOS are allways uppercase
			fulldir[i] = toupper(fulldir[i]);
		strcpy(Drives[drive]->curdir, fulldir);
		return true;
		}
	DOS_SetError(DOSERR_PATH_NOT_FOUND);
	return false;
	}
Bit8u DOS_FindDevice(char const * name) {
	/* should only check for the names before the dot and spacepadded */
	char fullname[DOS_PATHLENGTH];Bit8u drive;
//	if(!name || !(*name)) return DOS_DEVICES; //important, but makename does it
	if (!DOS_MakeName(name,fullname,&drive)) return DOS_DEVICES;

	char* name_part = strrchr(fullname,'\\');
	if(name_part) {
		*name_part++ = 0;
		//Check validity of leading directory.
		if(!Drives[drive]->TestDir(fullname)) return DOS_DEVICES;
	} else name_part = fullname;
   
	char* dot = strrchr(name_part,'.');
	if(dot) *dot = 0; //no ext checking

	static char com[5] = { 'C','O','M','1',0 };
	static char lpt[5] = { 'L','P','T','1',0 };
	// AUX is alias for COM1 and PRN for LPT1
	// A bit of a hack. (but less then before).
	// no need for casecmp as makename returns uppercase
	if (strcmp(name_part, "AUX") == 0) name_part = com;
	if (strcmp(name_part, "PRN") == 0) name_part = lpt;

	/* loop through devices */
	for(Bit8u index = 0;index < DOS_DEVICES;index++) {
		if (Devices[index]) {
			if (WildFileCmp(name_part,Devices[index]->name)) return index;
		}
	}
	return DOS_DEVICES;
}
Exemple #8
0
bool DOS_FileExists(char const* const name)
	{
	char fullname[DOS_PATHLENGTH];
	Bit8u drive;
	if (!DOS_MakeName(name, fullname, &drive))
		return false;
	return Drives[drive]->FileExists(fullname);
	}
void* DOS_CreateOpenFile(char const* const name)
	{
	char fullname[DOS_PATHLENGTH];
	Bit8u drive;
	if (!DOS_MakeName(name, fullname, &drive))
		return NULL;
	return Drives[drive]->CreateOpenFile(fullname);
	}
Bit32u DOS_GetCompressedFileSize(char const* const name)
	{
	char fullname[DOS_PATHLENGTH];
	Bit8u drive;
	if (!DOS_MakeName(name, fullname, &drive))
		return false;
	return Drives[drive]->GetCompressedSize(fullname);
	}
bool DOS_GetSFNPath(char const * const path,char * SFNPath,bool LFN) {
	char dir_current[DOS_PATHLENGTH + 1], pdir[LFN_NAMELENGTH], *p;
	Bit8u drive;char fulldir[DOS_PATHLENGTH],LFNPath[CROSS_LEN];
	char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH];
	int w=0;
	DOS_DTA dta(dos.dta());
	Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
	if (!DOS_MakeName(path,fulldir,&drive)) return false;
	sprintf(SFNPath,"%c:\\",drive+'A');
	strcpy(LFNPath,SFNPath);
	strcpy(dir_current,Drives[drive]->curdir);
	Drives[drive]->curdir,"";
	p = fulldir;
	if (*p==0) return true;
	for (char *s = strchr(p,'\\'); s != NULL; s = strchr(p,'\\')) {
		*s = 0;
		if (SFNPath[strlen(SFNPath)-1]=='\\')
			sprintf(pdir,"\"%s%s\"",SFNPath,p);
		else
			sprintf(pdir,"\"%s\\%s\"",SFNPath,p);
		if (!strrchr(p,'*') && !strrchr(p,'?')) {
			*s = '\\';
			p = s + 1;
			if (DOS_FindFirst(pdir,0xffff & DOS_ATTR_DIRECTORY & ~DOS_ATTR_VOLUME,false)) {
				dta.GetResult(name,lname,size,date,time,attr);
				strcat(SFNPath,name);
				strcat(LFNPath,lname);
				Drives[drive]->curdir,SFNPath+3;
				strcat(SFNPath,"\\");
				strcat(LFNPath,"\\");
			}
			else {
			return false;}
		} else {
			strcat(SFNPath,p);
			strcat(LFNPath,p);
			strcat(SFNPath,"\\");
			strcat(LFNPath,"\\");
			*s = '\\';
			p = s + 1;
			break;
		}
	}
	if (p != 0) {
		sprintf(pdir,"\"%s%s\"",SFNPath,p);
		if (!strrchr(p,'*')&&!strrchr(p,'?')&&DOS_FindFirst(pdir,0xffff & ~DOS_ATTR_VOLUME,false)) {
			dta.GetResult(name,lname,size,date,time,attr);
			strcat(SFNPath,name);
			strcat(LFNPath,lname);
		} else {
			strcat(SFNPath,p);
			strcat(LFNPath,p);
		}
	}
	Drives[drive]->curdir,dir_current;
	if (LFN) strcpy(SFNPath,LFNPath);
	return true;
}
Exemple #12
0
bool DOS_Canonicalize(char const* const name, char* const big)
	{
	// TODO Add Better support for devices and shit but will it be needed i doubt it :) 
	if (!DOS_MakeName(name, &big[3], (Bit8u *)big))
		return false;
	big[0] += 'A';
	big[1] = ':';
	big[2] = '\\';
	return true;
	}
Exemple #13
0
bool DOS_GetFileAttr(char const * const name,Bit16u * attr) {
	char fullname[DOS_PATHLENGTH];Bit8u drive;
	if (!DOS_MakeName(name,fullname,&drive)) return false;
	if (Drives[drive]->GetFileAttr(fullname,attr)) {
		return true;
	} else {
		DOS_SetError(DOSERR_FILE_NOT_FOUND);
		return false;
	}
}
Exemple #14
0
bool DOS_UnlinkFile(char const * const name) {
	char fullname[DOS_PATHLENGTH];Bit8u drive;
	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_GetFileAttrEx(char const* const name, struct stat *status, Bit8u hdrive)
	{
	char fullname[DOS_PATHLENGTH];
	Bit8u drive;
	bool usehdrive=hdrive>=0&&hdrive<DOS_FILES;
	if (usehdrive)
		strcpy(fullname,name);
	else if (!DOS_MakeName(name, fullname, &drive))
		return false;
	return Drives[usehdrive?hdrive:drive]->GetFileAttrEx(fullname, status);
	}
Exemple #16
0
bool DOS_Canonicalize(char const * const name,char * const big) {
//TODO Add Better support for devices and shit but will it be needed i doubt it :)
    Bit8u drive;
    char fullname[DOS_PATHLENGTH];
    if (!DOS_MakeName(name,fullname,&drive)) return false;
    big[0]=drive+'A';
    big[1]=':';
    big[2]='\\';
    strcpy(&big[3],fullname);
    return true;
}
Exemple #17
0
bool DOS_SetFileAttr(char const* const name, Bit16u /*attr*/) 
	// this function does not change the file attributs
	// it just does some tests if file is available 
	// returns false when using on cdrom (stonekeep)
	{
	char fullname[DOS_PATHLENGTH];
	Bit8u drive;
	if (!DOS_MakeName(name, fullname, &drive))
		return false;	
	Bit16u attrTemp;
	return Drives[drive]->GetFileAttr(fullname, &attrTemp);
	}
Exemple #18
0
bool DOS_ChangeDir(char const * const dir) {
	Bit8u drive;char fulldir[DOS_PATHLENGTH];
	if (!DOS_MakeName(dir,fulldir,&drive)) return false;
	
	if (Drives[drive]->TestDir(fulldir)) {
		strcpy(Drives[drive]->curdir,fulldir);
		return true;
	} else {
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
	}
	return false;
}
Exemple #19
0
static bool PathExists(char const * const name) {
	const char* leading = strrchr(name,'\\');
	if(!leading) return true;
	char temp[CROSS_LEN];
	strcpy(temp,name);
	char * lead = strrchr(temp,'\\');
	if (lead == temp) return true;
	*lead = 0;
	Bit8u drive;char fulldir[DOS_PATHLENGTH];
	if (!DOS_MakeName(temp,fulldir,&drive)) return false;
	if(!Drives[drive]->TestDir(fulldir)) return false;
	return true;
}
Exemple #20
0
static bool PathExists(char const* const name)
	{
	char temp[MAX_PATH_LEN];
	char* lead = strrchr(strcpy(temp, name), '\\');
	if (!lead || lead == temp)
		return true;
	*lead = 0;
	Bit8u drive;
	char fulldir[DOS_PATHLENGTH];
	if (!DOS_MakeName(temp, fulldir, &drive) || !Drives[drive]->TestDir(fulldir))
		return false;
	return true;
	}
Exemple #21
0
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;
	}
Exemple #22
0
bool DOS_SetFileAttr(char const * const name,Bit16u /*attr*/) 
// this function does not change the file attributs
// it just does some tests if file is available 
// returns false when using on cdrom (stonekeep)
{
	Bit16u attrTemp;
	char fullname[DOS_PATHLENGTH];Bit8u drive;
	if (!DOS_MakeName(name,fullname,&drive)) return false;	
	if (strncmp(Drives[drive]->GetInfo(),"CDRom ",6)==0 || strncmp(Drives[drive]->GetInfo(),"isoDrive ",9)==0) {
		DOS_SetError(DOSERR_ACCESS_DENIED);
		return false;
	}
	return Drives[drive]->GetFileAttr(fullname,&attrTemp);
}
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;
	}
}
Exemple #24
0
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;
    }
}
Exemple #25
0
bool DOS_MakeDir(char const * const dir) {
	Bit8u drive;char fulldir[DOS_PATHLENGTH];
	size_t len = strlen(dir);
	if(!len || dir[len-1] == '\\') {
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
		return false;
	}
	if (!DOS_MakeName(dir,fulldir,&drive)) return false;
	if(Drives[drive]->MakeDir(fulldir)) return true;

	/* Determine reason for failing */
	if(Drives[drive]->TestDir(fulldir)) 
		DOS_SetError(DOSERR_ACCESS_DENIED);
	else
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
	return false;
}
Exemple #26
0
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;
}
Exemple #27
0
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;
	}
Exemple #28
0
Bit8u DOS_FindDevice(char const * name)
	{
	// should only check for the names before the dot and spacepadded
	char fullname[DOS_PATHLENGTH];
	Bit8u drive;
//	if(!name || !(*name)) return DOS_DEVICES; //important, but makename does it
	if (!DOS_MakeName(name, fullname, &drive))
		return DOS_DEVICES;

	char* name_part = strrchr(fullname,'\\');
	if (name_part)
		{
		*name_part++ = 0;
		// Check validity of leading directory.
		if (!Drives[drive]->TestDir(fullname))
			return DOS_DEVICES;
		}
	else
		name_part = fullname;
   
	char* dot = strrchr(name_part, '.');
	if (dot)
		*dot = 0;	// no ext checking

	static char com[] = "COM1";
	static char lpt[] = "LPT1";
	// AUX is alias for COM1 and PRN for LPT1
	// A bit of a hack. (but less then before).
	if (!stricmp(name_part, "AUX"))
		name_part = com;
	else if (!stricmp(name_part, "PRN"))
		name_part = lpt;

	// loop through devices
	for (Bit8u index = 0; index < DOS_DEVICES; index++)
		if (Devices[index])
			if (WildFileCmp(name_part, Devices[index]->name))
				return index;
	return DOS_DEVICES;
	}
Exemple #29
0
bool DOS_RemoveDir(char const * const dir)
	{
	/* We need to do the test before the removal as can not rely on
	 * the host to forbid removal of the current directory.
	 * We never change directory. Everything happens in the drives.
	 */
	Bit8u drive;
	const char *testdir = dir;
	if (*testdir && testdir[1] == ':')
		{
		drive = (*testdir | 0x20)-'a';
		if (drive >= DOS_DRIVES || !Drives[drive])
			{
			DOS_SetError(DOSERR_INVALID_DRIVE);
			return false;
			}
		testdir += 2;
		}
	size_t len = strlen(testdir);
	char fulldir[DOS_PATHLENGTH];
	if (!len || !DOS_MakeName(dir, fulldir, &drive) || (*fulldir && testdir[len-1] == '\\'))
		{
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
		return false;
		}
	if (!Drives[drive]->TestDir(fulldir))											// Check if exists
		{
		DOS_SetError(DOSERR_PATH_NOT_FOUND);
		return false;
		}
	if (strcmp(Drives[drive]->curdir, fulldir) == 0)								// Test if it's current directory
		{
		DOS_SetError(DOSERR_REMOVE_CURRENT_DIRECTORY);
		return false;
		}
	if (Drives[drive]->RemoveDir(fulldir))
		return true;
	DOS_SetError(DOSERR_ACCESS_DENIED);												// Failed. We know it exists and it's not the current dir assume non empty
	return false;
	}
Exemple #30
0
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);
	}