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; }
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; } }
void DOS_Shell::CMD_DIR(char * args) { HELP("DIR"); char numformat[16]; char path[DOS_PATHLENGTH]; char sargs[CROSS_LEN]; std::string line; if(GetEnvStr("DIRCMD",line)){ std::string::size_type idx = line.find('='); std::string value=line.substr(idx +1 , std::string::npos); line = std::string(args) + " " + value; args=const_cast<char*>(line.c_str()); } bool optW=ScanCMDBool(args,"W"); ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); if (ScanCMDBool(args,"WP") || ScanCMDBool(args,"PW")) { optW=optP=true; } bool optB=ScanCMDBool(args,"B"); bool optAD=ScanCMDBool(args,"AD"); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } Bit32u byte_count,file_count,dir_count; Bitu w_count=0; Bitu p_count=0; Bitu w_size = optW?5:1; byte_count=file_count=dir_count=0; char buffer[CROSS_LEN]; args = trim(args); size_t argLen = strlen(args); if (argLen == 0) { strcpy(args,"*.*"); //no arguments. } else { switch (args[argLen-1]) { case '\\': // handle \, C:\, etc. case ':' : // handle C:, etc. strcat(args,"*.*"); break; default: break; } } args = ExpandDot(args,buffer); if (!strrchr(args,'*') && !strrchr(args,'?')) { Bit16u attribute=0; if(!DOS_GetSFNPath(args,sargs,false)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } if(DOS_GetFileAttr(sargs,&attribute) && (attribute&DOS_ATTR_DIRECTORY) ) { DOS_FindFirst(sargs,0xffff & ~DOS_ATTR_VOLUME); DOS_DTA dta(dos.dta()); strcpy(args,sargs); strcat(args,"\\*.*"); // if no wildcard and a directory, get its files } } if (!DOS_GetSFNPath(args,sargs,false)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } sprintf(args,"\"%s\"",sargs); if (!strrchr(args,'.')) { strcat(args,".*"); // if no extension, get them all } /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } *(strrchr(path,'\\')+1)=0; if (!DOS_GetSFNPath(path,sargs,true)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } if (*(sargs+strlen(sargs)-1) != '\\') strcat(sargs,"\\"); if (!optB) WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),sargs); /* Command uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); DOS_DTA dta(dos.dta()); bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { if (!optB) WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); dos.dta(save_dta); return; } do { /* File name and extension */ char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH+1]; Bit32u size;Bit16u date;Bit16u time;Bit8u attr; dta.GetResult(name,lname,size,date,time,attr); /* Skip non-directories if option AD is present */ if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; /* output the file */ if (optB) { // this overrides pretty much everything if (strcmp(".",uselfn?lname:name) && strcmp("..",uselfn?lname:name)) { WriteOut("%s\n",uselfn?lname:name); } } else { char * ext = empty_string; if (!optW && (name[0] != '.')) { ext = strrchr(name, '.'); if (!ext) ext = empty_string; else *ext++ = 0; } Bit8u day = (Bit8u)(date & 0x001f); Bit8u month = (Bit8u)((date >> 5) & 0x000f); Bit16u year = (Bit16u)((date >> 9) + 1980); Bit8u hour = (Bit8u)((time >> 5 ) >> 6); Bit8u minute = (Bit8u)((time >> 5) & 0x003f); if (attr & DOS_ATTR_DIRECTORY) { if (optW) { WriteOut("[%s]",name); size_t namelen = strlen(name); if (namelen <= 14) { for (size_t i=14-namelen;i>0;i--) WriteOut(" "); } } else { WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d %s\n",name,ext,"<DIR>",day,month,year,hour,minute,uselfn?lname:""); } dir_count++; } else { if (optW) { WriteOut("%-16s",name); } else { FormatNumber(size,numformat); WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d %s\n",name,ext,numformat,day,month,year,hour,minute,uselfn?lname:""); } file_count++; byte_count+=size; } if (optW) { w_count++; } } if (optP && !(++p_count%(22*w_size))) { CMD_PAUSE(empty_string); } } while ( (ret=DOS_FindNext()) ); if (optW) { if (w_count%5) WriteOut("\n"); } if (!optB) { /* Show the summary of results */ FormatNumber(byte_count,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); Bit8u drive=dta.GetSearchDrive(); //TODO Free Space Bitu free_space=1024*1024*100; if (Drives[drive]) { Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; Drives[drive]->AllocationInfo(&bytes_sector,§ors_cluster,&total_clusters,&free_clusters); free_space=bytes_sector*sectors_cluster*free_clusters; } FormatNumber(free_space,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); } dos.dta(save_dta); }