modfat problem : magic numbers in fat_Read()

I have rewritten a cgi routine that send to the client a file stored on the nand flash (with modfat),
the previously made routine works perfectly with a (global) buffer of 260 (or more) bytes.
Now, if RFBUFSIZE is 128 all is OK, when i increase this number to 256 the return code rc of the routine fat_Read() at the 2nd or 3rd call is -22 (EINVAL invalid argument)
When i change the value to 512, at the first calling of fat_Read() the rc is sometimes EPATHSTR (-306 Bad file/dir path string), other times EFSTATE (-319 File in an invalid state) or ECORRUPT (-321 filesystem corrupted)
If i execute fat_shell.c after the ECORRUPT error, the directory listing shows corrupt files (and the only solution is to format the partition).
I dont know how is it possible to corrupt the filesystem with a read command!!
This is the code, i dont expect that it’s correct, i have changed it so more times…:frowning:
The FATprtError print a human readable error from th rc.
(excuse me for my terrible english)


#define RFBUFSIZE 128
long rflencount;
int CGIreadfile(HttpState* state){
int rc,a,len,bytes;
char buffer[RFBUFSIZE];
char filename[7];
FATfile *file;

   switch (state->substate){
   	case 0:
        a=http_getCond(state,0);
        memset(filename,0,7);
        itoa(a,filename);
        rc=fat_Open(FATpart,filename,FAT_FILE, FAT_READONLY,file, NULL);
        printf("in READFILE %s",filename);
        FATprtError(rc);
        rflencount=file->de.fileSize;
        printf("rflencount = %ld
",rflencount);
        rflencount=(rflencount>65535l)?65535l:rflencount;
        if((rc<0)||(rflencount<1l)){
            state->substate=2;
            break;
        }
        rc=fat_Seek(file,0,SEEK_SET);
        printf("RF seek ");FATprtError(rc);
        memset(buffer,0,RFBUFSIZE);
        sprintf(buffer,"HTTP/1.0 200 OK
Content-Type: text/plain
Content-Disposition: attachment; filename=\"%d.hex\"

",a);		
        rc=http_write(state, &buffer[0], strlen(buffer));
        printf("header sent with rc=%d
",rc);
        state->substate++;
   		break;
   	case 1:
            //~ memset(buffer,0,RFBUFSIZE);
            len= (int)((rflencount>RFBUFSIZE)?RFBUFSIZE:rflencount);
            //~ printf("len=%d -",len);

                        //the "guilty" line...
   			bytes=fat_Read(file,buffer,len);


             //~ printf("rc Fread=%d -",bytes);
            //~ FATprtError(bytes);
            if (bytes>0){
                if (http_write(state, buffer, bytes)==0){
                rflencount-=(long)bytes;
                //~ printf("rflc %ld
",rflencount);
                if(rflencount<1)
                    state->substate++;
                }
            } else {//  EOF
                FATprtError(bytes);
   	        state->substate++;
	    } 
   		break;
	case 2:
        default:
		rc=fat_Close(file);
        FATprtError(rc);
        return 1;//CGI
   		break;
}
return 0;
}

EPATHSTR and ECORRUPT errors occur on subsequent accesses (with fat_Open() ) to the file after EINVAL return code is returned.

Your file handle is not a static variable, it is an unitialized pointer. You must reserve storage space for the file handle. You also must preserve the handle returned from the fat_Open call. The lines you should change are shown below:


   ...
static FATfile file;
   ...
rc=fat_Open(FATpart,filename,FAT_FILE, FAT_READONLY,&file, NULL);
   ...
bytes=fat_Read(&file,buffer,len);
   ...
rc=fat_Close(&file);
   ...

it’s true!!how stupid i am!!:open_mouth:
in the previous version there was a global buffer AND a global pfile pointer, and the structure was preserved between subsequent calls…
i’m feeling really stupid…:frowning:
THANKS BSPROUSE!!!