/* Utility for reading long filenames (WIN'95) ;) I've used the BOOT SECTOR INFORMATION.So if you wanna change it you can to make it use BIOS services for getting the specific info... (The problem exists when the BOOT INFO is deleted in the floppy drive) So Use INT 25h fer getting the BPB & store all values in the variables If you experience any problems,I'd be glad if you can give me a call. If you change the code do let me know ! One good thing is you CAN SEARCH FOR DELETED FILES ALSO USING THIS UTILITY !!! 29/08/96 Send me EMAIL for all comments at: astav@giasbga.vsnl.net.in Û²±° Vatsa °±²Û Srivatsa Srinivasan. */ #define _SAFE 100 //safe memory area #include #include #include #include #include //Just fer one function current working directory :(( #include typedef unsigned long ULI_; typedef unsigned int UI_; typedef unsigned char UC_; ULI_ SPC;//Sectors per Cluster ULI_ NOC;//Number of Clusters ULI_ BPC;//Bytes per cluster ULI_ BPS;//Bytes per sector ULI_ NOF;//Number of FAT ULI_ SPF;//Sectors per FAT ULI_ SRD;//Sector root directory ULI_ NRE;//Number of root directory entries ULI_ RSB;//Reserved sectors at beggining (This is used when you compress the disk!!) int drive=0;//A=0,B=1,C=2 struct file { UC_ filename[14]; UC_ *long_filename; UC_ attrib; UI_ time; UI_ date; ULI_ cluster; ULI_ sector; ULI_ file_size; }; struct FileControl { char path[MAXPATH]; //disk functions file path without long filenames :(( ULI_ df_file_number; ULI_ df_sect_at; ULI_ df_current_off; ULI_ df_check_FAT; struct file FI; }; int get_boot_info() { struct fatinfo diskinfo; UC_ *data; int flag; cprintf("\r\nGetting BOOT SECTOR info... "); drive=getdisk(); getfat(drive+1,&diskinfo); SPC=diskinfo.fi_sclus; NOC=diskinfo.fi_nclus; BPC=diskinfo.fi_bysec; data = (char *) calloc(BPS+_SAFE, sizeof(char)); absread(drive,1L,0L,data); NOF=data[0x10]; SPF=data[0x17]*256L+data[0x16]; RSB=data[0x0F]*256L+data[0x0E]; BPS=data[0x0C]*256L+data[0x0B]; NRE=data[0x12]*256L+data[0x11]; cprintf("DONE :)"); if(RSB!=1) { cprintf("\r\n Probably has a device driver & is compressed.No Probs."); } free(data); return 0; } UI_ get_ROOT_sector() { SRD=(SPF*NOF)+RSB; return SRD; } char *get_path_at(char *path,int at) { int t=0,a=0,b=0; char filename[80]; strcpy(filename,""); while(path[a++]!='\\'); while(t!=at) { b=0; while(path[a]!='\\' && path[a]!='\0') filename[b++]=path[a++]; while(path[a]=='\\') a++; t++; if(path[a]=='\0' && at!=t) { b=0; break;} } filename[b]='\0'; return filename; } ULI_ clust_to_sect(ULI_ var) { return ((var-2)*SPC)+(NRE/16)+(NOF*SPF+RSB); } ULI_ sect_to_clust(ULI_ var) { // if(var<(NRE/16)+(NOF*SPF+1)) return var; return ((var-(NRE/16)-(NOF*SPF+RSB))/SPC)+2; } void load_structure(UC_ *data,struct file *temp,int aa) { int t=0,a=0; data+=aa*32; while(t<0x08 && data[t]!=' ') temp->filename[a++]=data[t++]; temp->filename[a++]='.'; t=0x08; while(t<0x0B && data[t]!=' ') temp->filename[a++]=data[t++]; if(temp->filename[a-1]=='.') a--; temp->filename[a]='\0'; a=0; t=0x0B; temp->attrib=data[t++]; t=0x16; temp->time=data[t+1]*256L+data[t]; t+=2; temp->date=data[t+1]*256L+data[t]; t+=2; temp->cluster=(data[t+1]*256L); temp->cluster+=data[t]; t+=2; temp->sector=clust_to_sect(temp->cluster); temp->file_size = data[t+3] & 0xff; temp->file_size<<=8; temp->file_size += data[t+2] & 0xff; temp->file_size<<=8; temp->file_size += data[t+1] & 0xff; temp->file_size<<=8; temp->file_size += data[t] & 0xff; temp->long_filename=0; } ULI_ get_link_cluster(ULI_ clust) { ULI_ sector=0,os; ULI_ next; UC_ *data; if(NOC>=4087L) sector=clust/256L+RSB; else sector=clust/340L+RSB; data = (char *) calloc(BPS+_SAFE, sizeof(char)); if(data==0) { cprintf("Not enough memory to read FAT"); exit(1); } absread(drive,1,sector,data); if(NOC>=4087L) { sector=clust-((sector-RSB)*256L); sector*=2; next=data[sector+1]*256L+data[sector]; } else //Why does DOS have to be so smart? 12 bits ? That's not FAT ;) { //This is just an aprox. if u know any other way USE IT! sector=clust-((sector-1)*341.333333333L); os=sector*1.5; next=data[os+1]*256L+data[os]; if(fmod(sector,2)==0) next&=0x0FFF; else next>>=4; } free(data); if(next>0x0FF8 && next<0x0FFF && NOC<4087L) next=clust; // if(next>0x0FFF8 && next<0x0FFFF && NOC>=4087L) next=clust; // if(next==0) { cprintf("\r\n The file reports that it occupies a certain area"); cprintf("\r\n but does not show the same in FAT1 ,Run some Disk Scanner FAST"); cprintf("\r\n :(( ... Taking default values"); next=clust+1; } return next; } struct file *get_first(struct FileControl *FC) { int t=1,max_numb=BPS/32; char present_search[80]; ULI_ cluster; UC_ *data; data = (UC_ *) calloc(BPS+_SAFE, sizeof(char)); FC->df_sect_at=get_ROOT_sector(); FC->df_check_FAT=0; FC->df_current_off=0; if(strcmp(FC->path,"\\")==0) return &FC->FI; absread(drive,1,FC->df_sect_at,data); strcpy(present_search,get_path_at(FC->path,t)); for(;;) { if(FC->df_current_off>=max_numb) { FC->df_check_FAT++; if(FC->df_check_FAT>=SPC) { // cprintf("\r\n Verifying FAT ... "); if(FC->df_sect_at>=NOF*SPF+RSB && FC->df_sect_at<=NOF*SPF+RSB+NRE/16) FC->df_sect_at++; //This means you're in the Root Directory! else FC->df_sect_at=clust_to_sect(get_link_cluster(sect_to_clust(FC->df_sect_at))); FC->df_check_FAT=0; // cprintf(" DONE :)"); } else FC->df_sect_at++; absread(drive,1,FC->df_sect_at,data); FC->df_current_off=0; } load_structure(data,&FC->FI,FC->df_current_off); if(FC->FI.filename[0]=='\0') break; if(strcmp(present_search,FC->FI.filename)==0) { t++; load_structure(data,&FC->FI,FC->df_current_off); strcpy(present_search,get_path_at(FC->path,t)); if(present_search[0]=='\0') { cprintf("\r\n -- Path wildcard found correct :) --",t); cprintf("\r\n PATH : %s",FC->path); FC->df_sect_at=FC->FI.sector; FC->df_current_off=0; FC->df_check_FAT=0; free(data); return &FC->FI; } FC->df_sect_at=FC->FI.sector; FC->df_current_off=-1; FC->df_check_FAT=0; absread(drive,1,FC->df_sect_at,data); } FC->df_current_off++; } cprintf("\r\n -- Unable to trace path :( --"); free(data); return 0; } struct file *get_next(struct FileControl *FC) { int max_numb=BPS/32; ULI_ cluster; UC_ *data; // if(FC->FI.long_filename!=NULL) free(FC->FI.long_filename); //deallocate previous allocated memory! data = (UC_ *) calloc(BPS+_SAFE, sizeof(char)); absread(drive,1,FC->df_sect_at,data); if(FC->df_current_off>=max_numb) { FC->df_check_FAT++; if(FC->df_check_FAT>=SPC) { // cprintf("\r\n Verifying FAT ... "); if(FC->df_sect_at>=NOF*SPF+RSB && FC->df_sect_at<=NOF*SPF+RSB+NRE/16) FC->df_sect_at++; else { cluster=sect_to_clust(FC->df_sect_at); cluster=get_link_cluster(cluster); FC->df_sect_at=clust_to_sect(cluster); } FC->df_check_FAT=0; // cprintf(" DONE :)"); } else FC->df_sect_at++; // cprintf("\r\n Reading.. "); absread(drive,1,FC->df_sect_at,data); FC->df_current_off=0; } load_structure(data,&FC->FI,FC->df_current_off); if(FC->FI.filename[0]=='\0') { free(data);return 0;} FC->df_current_off++; free(data); return &FC->FI; } struct file *get_long(struct FileControl *FC) { int set_1=2,lv=0,lt=0,max_long,k; ULI_ cluster; UC_ *data,*long_data; char *filename; data = (UC_ *) calloc(BPS+_SAFE, sizeof(char)); if(data==0) { cprintf("\r\n NO_MEM 1"); exit(1); } while(set_1!=0) { absread(drive,1,FC->df_sect_at,data); if(FC->df_current_off>=BPS/32) { FC->df_check_FAT++; if(FC->df_check_FAT>=SPC) { // cprintf("\r\n Verifying FAT ... "); if(FC->df_sect_at>=NOF*SPF+RSB && FC->df_sect_at<=NOF*SPF+RSB+NRE/16) FC->df_sect_at++; else { cluster=sect_to_clust(FC->df_sect_at); cluster=get_link_cluster(cluster); FC->df_sect_at=clust_to_sect(cluster); } FC->df_check_FAT=0; // cprintf(" DONE :)"); } else FC->df_sect_at++; // cprintf("\r\n Reading.. "); absread(drive,1,FC->df_sect_at,data); FC->df_current_off=0; } load_structure(data,&FC->FI,FC->df_current_off); if(FC->FI.filename[0]=='\0') { free(data); if(set_1!=2) free(long_data); return 0; } FC->df_current_off++; if(FC->FI.cluster!=0 && set_1==1) { lt=(max_long+1)*32; lt--; lv=0; while(lt>0) { lt--; for(k=0;k<4;k++) { filename[lv]=long_data[lt]; lt-=2; lv++; } filename[lv]=long_data[lt]; lt-=5; lv++; for(k=0;k<5;k++) { filename[lv]=long_data[lt]; lt-=2; lv++; } filename[lv]=long_data[lt]; lt-=4; lv++; for(k=0;k<2;k++) { filename[lv]=long_data[lt]; lt-=2; lv++; } } FC->FI.long_filename=filename; // free(long_data); // cprintf("<- DONE! ;) "); set_1=0; } else if(FC->FI.cluster==0 && FC->FI.attrib==0xF && (set_1==0 || set_1==2) && FC->FI.filename[0]!=229) { // cprintf("\r\n Recieving LONG ..... ->"); set_1=1; lt=(FC->df_current_off-1)*32; max_long=(data[lt]-'A'); long_data = (UC_ *) calloc((max_long+1)*32L+_SAFE, sizeof(char)); filename = (UC_ *) calloc((max_long+1)*15L+_SAFE, sizeof(char)); if(long_data==0) { cprintf("\r\n NO_MEM 2"); exit(1); } if(filename==0) { cprintf("\r\n NO_MEM for longfilename"); exit(1); } } if(set_1==1) { lt=(FC->df_current_off-1)*32; lt=FC->df_current_off*32-1; k=0; while(k<32) { long_data[lv]=data[lt]; k++; lv++; lt--; } // cprintf("°±"); } else if(set_1==2 && ( FC->FI.attrib & 0x08 )==0) break; //Why care about disk volumes ?? } free(data); if(set_1!=2) free(long_data); return &FC->FI; } //Cut this if you dont need this..... //-------------------------------------------------------------------- ///* int to_day(ULI_ date) { date&=0x001F; return date; } int to_month(ULI_ date) { date&=0x01E0; date>>=5; return date; } int to_year(ULI_ date) { date&=0xFE00; date>>=9; return date+1980; } int to_seconds(ULI_ date) { date&=0x001F; return date*2; }//seconds can NEVER be odd! int to_min(ULI_ date) { date&=0x07E0; date>>=5; return date; } int to_hour(ULI_ date) { date&=0xF800; date>>=0xB; return date; } void main ( argc, argv ) // Just an example.. int argc ; char *argv[] ; { struct FileControl FC; //Main structure like ffblk in ULI_ t=0; char page=0,scroll=0,*temp; // cprintf("\r\n Enter Path : "); // scanf("%s",FC.path); if(argc==2 || argc==1 ) { getcwd(FC.path,MAXPATH); temp=FC.path; temp+=2; //Best way to shift text ? Huh ? Power of C ! strcpy(FC.path,temp); if(argc==2 && (strcmp(argv[1],"/p")==0 || strcmp(argv[1],"/P")==0)) scroll=1; } else { strcpy(FC.path,argv[1]); if(argc>2 && (strcmp(argv[2],"\\p")==0 || strcmp(argv[2],"\\P")==0)) scroll=1; t=0; while(FC.path[t]!='\0') { FC.path[t]=toupper(FC.path[t]); t++; } } t=0; get_boot_info(); // :(( This you'll have to do at the beg of your prog :(( if(get_first(&FC)!=0)//something like findfirst() { while(get_long(&FC)!=0)//something like findnext() { if(FC.FI.filename[0]!=229) // Deleted file (Have programmed to get the deleted file too so dont display it) { if((FC.FI.attrib&0x10)!=0) { textcolor(15); cprintf("\r\n%ld> %7ld %02d-%02d-%4d %02d:%02d:%02d ° %15s ",t ,FC.FI.file_size,to_day(FC.FI.date),to_month(FC.FI.date),to_year(FC.FI.date) ,to_hour(FC.FI.time),to_min(FC.FI.time),to_seconds(FC.FI.time),FC.FI.filename); } else { textcolor(7); cprintf("\r\n%ld> %7ld %02d-%02d-%4d %02d:%02d:%02d %15s ",t ,FC.FI.file_size,to_day(FC.FI.date),to_month(FC.FI.date),to_year(FC.FI.date) ,to_hour(FC.FI.time),to_min(FC.FI.time),to_seconds(FC.FI.time),FC.FI.filename); } if(FC.FI.long_filename!=0) cprintf(" ³ %s",FC.FI.long_filename); t++; if(scroll==1) { page++; if(page>20) { getch(); page=0; } } } if(FC.FI.long_filename!=NULL) free(FC.FI.long_filename); //deallocate previous allocated memory for long filenames! } textcolor(7); cprintf("\r\n\n Total Enteries = %ld \r\n",t); } } //*/