win32utils-devel@rubyforge.org
2004-Nov-21 18:16 UTC
[Win32utils-devel] win32-file, overlapped added
Hi all, I''ve got overlapped and offset support in both nread and nwrite. The only thing left before I want to release this (as 0.4.0) is to get NO_BUFFERING to work. Unfortunately, I can''t get it to work. Park, I looked at that site you sent (and borrowed some code from it), but I don''t see anything special happening for NO_BUFFERING. I thought it required VirtualAlloc() but I''m not sure. If anyone has any ideas on that, please let me know. Thanks. Regards, Dan
win32utils-devel@rubyforge.org
2004-Nov-21 22:20 UTC
[Win32utils-devel] win32-file, overlapped added
Hi,> > Hi all, > > I''ve got overlapped and offset support in both nread and nwrite. The only > thing left before I want to release this (as 0.4.0) is to get NO_BUFFERING > to work. Unfortunately, I can''t get it to work. > > Park, I looked at that site you sent (and borrowed some code from it), but I > don''t see anything special happening for NO_BUFFERING. I thought it > required VirtualAlloc() but I''m not sure. > > If anyone has any ideas on that, please let me know. Thanks. >The problem is due to ReadFile cannot read large file at one call in case of larger than 0x3000000 bytes with NO_BUFFERING. I tested using while loop and it works. Just borrow some code from it again.:)> Regards, > > Dan >Regards, Park Heesob --MIME Multi-part separator--
win32utils-devel@rubyforge.org
2004-Nov-22 13:51 UTC
[Win32utils-devel] win32-file, overlapped added
> The problem is due to ReadFile cannot read large file at one > call in case of larger than 0x3000000 bytes with > NO_BUFFERING. I tested using while loop and it works. Just > borrow some code from it again.:)I must be dense, because even if I try to use that option on a small file, I get "the parameter is incorrect". What am I missing? Dan
win32utils-devel@rubyforge.org
2004-Nov-22 19:25 UTC
[Win32utils-devel] win32-file, overlapped added
Hi,> > > The problem is due to ReadFile cannot read large file at one > > call in case of larger than 0x3000000 bytes with > > NO_BUFFERING. I tested using while loop and it works. Just > > borrow some code from it again.:) > > I must be dense, because even if I try to use that option on a small > file, I get "the parameter is incorrect". What am I missing? > > Dan >Here is my test code for case NO_BUFFERING: int getsectorcount(int x,char* str) { /*a function that returns number of sectors in file*sectorsize */ DWORD y[4]; if(GetDiskFreeSpace(str,&y[0],&y[1],&y[2],&y[3])==0) rb_raise(cFileError,ErrorDescription(GetLastError())); y[0]=x%y[1]; if(y[0]!=0)x+=y[1]-y[0]; return x; } /* * Uses the native ReadFile() behind the scenes. */ static VALUE file_nread(int argc, VALUE* argv, VALUE self){ OVERLAPPED olap; OpenFile *fptr; int fd; BOOL rv; HANDLE hFile; DWORD dwBytesToRead, dwBytesRead; int dwToRead, dwRead; VALUE rbLength, rbOffset, rbBuffer; char* lpBuffer = NULL; char* lpPtr = NULL; VALUE rbPath; char lpPath[256]; rbPath = file_get_path(self); strcpy(lpPath,StringValuePtr(rbPath)); lpPath[3] = 0; rb_scan_args(argc,argv,"02",&rbLength,&rbOffset); GetOpenFile(self, fptr); fd = _fileno(fptr->f); hFile = (HANDLE)_get_osfhandle(fd); memset(&olap, 0, sizeof(OVERLAPPED)); olap.Offset = 0; olap.OffsetHigh = 0; olap.hEvent = NULL; // TODO: Allow Win32::Event object if(Qnil != rbOffset) olap.Offset = NUM2INT(rbOffset); if(hFile == INVALID_HANDLE_VALUE) rb_raise(cFileError,ErrorDescription(GetLastError())); if(NIL_P(rbLength)){ dwBytesToRead = GetFileSize(hFile,NULL); } else{ dwBytesToRead = NUM2UINT(rbLength); } lpBuffer = malloc(getsectorcount(dwBytesToRead,lpPath)); memset(lpBuffer,0x00,dwBytesToRead); if(NULL == lpBuffer) rb_raise(cFileError,"malloc() call failed in nread() method"); lpPtr = lpBuffer; dwRead = 0; dwToRead = getsectorcount(dwBytesToRead,lpPath); if(dwBytesToRead>0x1000000) while(dwToRead>0) { if(dwToRead>0x1000000) rv = ReadFile( hFile, (LPVOID)lpPtr, 0x1000000, &dwRead, &olap ); else rv = ReadFile( hFile, (LPVOID)lpPtr, dwToRead, &dwRead, &olap ); if(0 == rv) rb_raise(cFileError,ErrorDescription(GetLastError())); lpPtr += 0x1000000; dwToRead -= 0x1000000; dwBytesRead += dwRead; } else { rv = ReadFile( hFile, (LPVOID)lpPtr, dwToRead, &dwBytesRead, &olap ); if(0 == rv) rb_raise(cFileError,ErrorDescription(GetLastError())); } if(dwBytesToRead != dwBytesRead) rb_raise(cFileError,"bytes to read != bytes actually read"); // This exchange is necessary so that we don''t have a memory leak (I think) rbBuffer = rb_str_new(lpBuffer,dwBytesRead); free(lpBuffer); return rbBuffer; } Regards, Park Heesob --MIME Multi-part separator--